Может ли быть так, что sizeof (T*)!= sizeof (const T*)?


я спорю с моим боссом об этом. Они говорят: "Да они могут быть разными."

возможно sizeof(T*) != sizeof(const T*) для типа T?

4 66

4 ответа:

нет, они не могут быть разными. Для достаточно разных T1 и T2,sizeof(T1 *) можно sizeof(T2 *), а если T2 это просто const T1, тогда:

3.9.2 типы соединений [основные.соединение]

3 [...] Указатели на cv-квалифицированные и cv-неквалифицированные версии (3.9.3) совместимых с макетом типов должны иметь одинаковые требования к представлению значений и выравниванию (3.11). [...]

и любой типа T макет-совместим с самим собой:

3.9 типы [основная.типы]

11 Если два типа T1 и T2 имеют тот же тип, то T1 и T2 are макет-совместимый типы. [...]


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

3.9 типы [основная.типы]

4 The представление объектов объект типа T последовательность Nunsigned char объекты, занятые объектом типа T, где N равна sizeof(T). Элемент представление значения объекта-это набор битов, которые содержат значение типа T. Для тривиально копируемым типы, представление значения-это набор битов в представлении объекта, который определяет стоимостью, который является одним дискретным элементом реализации определенного набора значений.44

44) цель состоит в том, что модель памяти C++ совместима с моделью языка программирования ISO/IEC 9899 C.

суть требования, причина, по которой он не просто говорит, что два типа имеют одно и то же представление объекта, такова это T * и const T * не только имеют одинаковое количество битов, но и то, что это те же биты в T * и const T *, которые составляют стоимость. Это должно гарантировать не только это sizeof(T *) == sizeof(const T *), а это означает, что вы можете использовать memcpy чтобы скопировать a T * значение указателя на const T * значение указателя или наоборот и получить значимый результат, тот же результат, который вы получите с const_cast.

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

микрочип выпустил такой компилятор C, где sizeof(T*) было 2, но sizeof(const T*) было 3 года.

компилятор C не был совместим со стандартами несколькими способами, поэтому это ничего не говорит об этом (я подозреваю, что это не так, и другие ответы согласны).

Хм, это очень эзотерично, но я думаю, что теоретически есть может быть архитектурой, которая имеет, скажем, 256 байт ОЗУ в адресе 0 и, скажем, несколько килобайт ПЗУ в более высоких адресах. А там может быть компилятором, который будет создавать 8-битный указатель для int *i потому что 8 бит достаточно для хранения адреса любого объекта в сильно ограниченной области ОЗУ, и любой изменяемый объект, конечно, неявно известен в области ОЗУ. Указатели типа const int *i потребуется 16 бит, так что они могли указывать на любое место в адресном пространстве. 8-битный указатель int *i может быть приведено к 16-битному указателю const int *i (но не наоборот), поэтому жидкотекучести требование стандарта C может быть удовлетворен.

но если есть такая архитектура в existense, я бы хотел ее увидеть (но не писать код для нее):)

Что касается стандартного C++, они не могут отличаться. C и c++ похожи в этом отношении.

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

в этом случае, это вероятный. Вы вполне можете обнаружить, что указатель на ROM (следовательно, const) имеет другой размер, чем указатель на RAM (const или non const.)

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