Подтвердить что ты не робот

Имеет ли 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?

4b9b3361

Ответ 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&, который может находиться в любом месте.