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

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

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

Ответ 1

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

3.9.2 Типы соединений [basic.compound]

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

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

3.9 Типы [basic.types]

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


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

3.9 Типы [basic.types]

4 Объектным представлением объекта типа T является последовательность N unsigned char объектов, занятых объектом типа T, где N равно sizeof(T). Представление значения объекта представляет собой набор битов, которые содержат значение типа T. Для тривиально копируемых типов представление значений представляет собой набор бит в представлении объекта, который определяет значение, которое является одним дискретным элементом определенного набора значений. 44

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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

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

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