Имеет ли sizeof (T) == sizeof (const T) и alignof (T) == alignof (const T)
Кажется разумным предположить, что T
и const T
будут двух типов, которые будут одинакового размера и имеют одинаковое выравнивание, но, подумав о некоторых реальных системах, кажется, что они могут быть разными.
Позвольте мне объяснить:
Предположим, у вас есть система с двумя типами памяти: RAM и Flash (которая только для чтения). ОЗУ 8-битная адресуемая, а Flash - только 16-битная адресуемая. Предположим, что это T
:
struct T
{
uint8_t x;
uint16_t y;
};
В адресной ОЗУ с байтом эта структура будет иметь длину 3 байта.... но в адресной Flash-адресе с двойным байтом (где будет находиться переменная const
) эта структура должна быть длиной не менее 4 байтов, из-за проблем с выравниванием.
Итак, вот мой вопрос:
Соответствуют ли стандарты c и С++ размерам и выравниванию типов const
и non const
?
Ответы
Ответ 1
Раздел 3.9.3:
Квалифицированные или cv-неквалифицированные версии типа различаются типы; однако они должны иметь одинаковое представление и выравнивание требования (3.11). 53
"cv-qualified" здесь относится к const
и volatile
. Так что ответ: да.
const
и volatile
указывать только ограничения/атрибуты доступа к указанному объекту. Они не считаются частью самого базового типа; следовательно, они не могут влиять на свойства типа.
Ответ 2
Да, это гарантируется [basic.type.qualifier]/1
Квалифицированные или cv-неквалифицированные версии типа представляют собой различные типы; однако они должны иметь те же требования к представлению и выравниванию (3.11).
Ответ 3
В адресной памяти с байтом эта структура будет иметь длину 3 байта.... но в адресной Flash-адресе с двойным байтом (где const-переменная будет существовать), эта структура должна иметь длину не менее 4 байтов, из-за проблем с выравниванием.
Однако компилятор не может сделать вывод, что только потому, что он const
здесь, он сохраняется в ПЗУ. Там может быть много других вещей, которые могут помешать этому, например mutable
, или просто динамически разместить const T
в стеке или вручную поместить его в кучную память в ОЗУ или тысячу других вещей. Вы также можете иметь const T&
, который может находиться в любом месте.