2012-06-26 2 views
4

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

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

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

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

+0

Я считаю, что ** C++ 11 ** гарантирует это ** ** C++ 03 **. Я позволю кому-то еще опубликовать фактический ответ с кавычками из стандарта. –

+0

boost :: optional? – Puppy

+0

@ K-ballo: Я не думаю, что C++ 11 гарантирует это. Он добавил 'alignas' для этой цели. – Nawaz

ответ

7

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

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

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

Edit: лучше ответ:

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

1

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

+0

То же правило применяется к двумерным массивам, например 'char a [M] [N]'? –

+0

@ MichałGórny Я так считаю, так как они на самом деле просто одномерные. –

9

В C++ 11, правильный способ сделать это заключается в следующем:

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

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

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

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

Также обратите внимание, что аргумент alignas может быть положительное целое значение Или типа. Таким образом, оба они эквивалентны:

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

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

+3

** C+++ **, какой хороший язык был бы! : P –

+0

@ Наваз: K-ballo был (с юмором) со ссылкой на ваше вступительное замечание «In C++ + 11». –

+0

@DavidHammen: Ой ... Я этого не заметил. – Nawaz

Смежные вопросы