Гарантии выравнивания статического массива символов

Я хочу знать гарантии выравнивания статически распределенного массиваchar, Глядя на другие вопросы SO, я нашел некоторые, касающиеся динамически распределенных массивовchar.

Для статически распределенныхchar массивы, выровнены ли они так, что я могу разместить в них новый любой тип (при условии, что он достаточно большой)? Или это относится только к динамически распределенным?

char buff[sizeof(T)];
T * pT = (T*) buff;
new(pT) T(); // well defined?
...
pT->~T();

Если нет, как я могу преодолеть эту проблему?

 Nawaz26 июн. 2012 г., 21:36
@ K-балл: я не думаю, что C ++ 11 гарантирует это. Добавилalignas для этой цели.
 Puppy26 июн. 2012 г., 21:35
повышение :: опциональный?
 K-ballo26 июн. 2012 г., 21:31
я верюC++11 гарантирует это времяC++03 не. Я позволю кому-то еще опубликовать фактический ответ с цитатами из стандарта.
 K-ballo26 июн. 2012 г., 21:38
@Nawaz: Это было мое понимание от3.11/6 [basic.align], что ты думаешь? Я правильно понял?
 James Caccese16 июл. 2012 г., 20:36
@ K-балл: Я уверен, что вы ошиблись. 3.11 / 6 говорит, что типы символов имеют самое слабое выравнивание, а 3.11 / 5 говорит, что более строгие выравнивания (с большими значениями выравнивания) удовлетворяют более слабым выравниваниям (с меньшими), а не наоборот. Это сводится к тому, что вы можете использовать тип символа для выровненной области памяти, если вы позаботитесь о выравнивании. Следуйте ссылке 3.11 / 6 в примечании 7.6.2 (спецификатор выравнивания), чтобы увидеть один способ сделать это. Другим способом было бы перераспределить массив символов и использовать указатель смещения внутри массива при соответствующем выравнивании.

Ответы на вопрос(3)

sizeof(element_type) bytes - для char это 1 байт, что в основном гарантирует отсутствие выравнивания.

 14 авг. 2012 г., 00:11
@ Micha & # x142; G & rf; rny; я верю в это, поскольку они на самом деле просто одномерные.
 13 авг. 2012 г., 23:57
Применяется ли то же правило к двумерным массивам, какchar a[M][N]?

char alignas(T) buff[sizeof(T)]; //Notice 'alignas' as
T * pT = (T*) buff;
new(pT) T(); // well defined!

Обратите внимание на использованиеalignas.

ЕслиT это аргумент шаблона, то лучше использоватьstd::alignment_of шаблон класса как:

char alignas(std::alignment_of<T>::value) buff[sizeof(T)]; 

Также обратите внимание, что аргументalignas может бытьpositive integral value Или жеtype, Так что оба они эквивалентны:

char alignas(T)          buff[sizeof(T)];
char alignas(alignof(T))  buff[sizeof(T)]; //same as above

Второй используетalignof который возвращает целое значение типаstd::size_t.

 26 июн. 2012 г., 21:49
@Nawaz: К-балл (с юмором) имел в виду ваш «В C +++ 11». Вступительное замечание
 26 июн. 2012 г., 21:38
C+++какой хороший язык это будет! :П
 26 июн. 2012 г., 21:50
@DavidHammen: упс ... я этого не заметил.
 26 июн. 2012 г., 22:03
@AProgrammer: это была опечатка. я имел в видуalignas(alignof(T)) неalignas(sizeof(T))
 26 июн. 2012 г., 21:57
@ Наваз, я не думаю, что alignas (T) - это то же самое, что alignas (sizeof (T)). Например, для структуры выравнивание является одним из наиболее строго выровненных членов, и это меньше, чем размер структуры для любой структуры, которая имеет более одного члена.
Решение Вопроса

вы можете использовать трюк объединения.

union
{
    char buff[sizeof(T)];
    uint64_t dummy;
};

Здесь выравнивание будет гарантировано для самого большого элемента в объединении. И, конечно, вы должны обернуть эту злобу в хороший класс.

Edit: better answer:

Конечно, вы могли бы быть еще лучше, используяboost::aligned_storage или жеalignas для C ++ 11.

Ваш ответ на вопрос