Дает ли переинтерпретация_приведения интеграла к типу указателя и обратно одно и то же значение?

Согласно http://en.cppreference.com/w/cpp/language/reinterpret_cast, Известно, что reinterpret_cast указатель на интеграл достаточного размера и обратно дают одно и то же значение. Мне интересно, верно ли обратное по стандартам. То есть, дает ли reinterpret_cast интеграл для типа указателя достаточного размера и обратно одно и то же значение?


person Lingxi    schedule 11.03.2015    source источник
comment
Нет, это не гарантируется. Например, разные целые числа могут преобразовываться в один и тот же адрес.   -  person n. 1.8e9-where's-my-share m.    schedule 11.03.2015
comment
@н.м. Не могли бы вы привести конкретный пример? Обратите внимание, что здесь используется reinterpret_cast для выполнения преобразования.   -  person Lingxi    schedule 11.03.2015
comment
Возьмем архитектуру 8086. Целое число 0x10002000L при интерпретации как 0x1000:0x2000 (сегмент и смещение) соответствует физическому адресу 0x12000. Так же как и целое число 0x12000000L. Ничто не мешает компилятору преобразовать сегмент 0x10002000L в сегмент и смещение 0x1200:0x0000, а затем преобразовать его обратно в 0x12000000L. В старые добрые времена это было известно как нормализация огромных указателей.   -  person n. 1.8e9-where's-my-share m.    schedule 11.03.2015
comment
Кроме того, в некоторых системах (архитектура 8051) объем памяти настолько мал, что нет типов указателей, достаточно больших для хранения, например, uint32_t. 8051 поддерживает 4 типа указателей: 1 байт (idata), 1 байт (pdata), 2 байта (xdata) и 3 байта (общий указатель).   -  person Mark Lakata    schedule 11.03.2015
comment
Нет, преобразование целого числа в указатель обратно в целое число не гарантируется. Цитата из cppreference: ...Указатель преобразован в целое число достаточного размера и обратно к тому же типу указателя гарантированно будет иметь исходное значение, в противном случае результирующий указатель не может быть безопасно разыменован (обратное преобразование в обратном направлении не гарантируется; один и тот же указатель может иметь несколько целочисленных представлений)....   -  person Petr Vepřek    schedule 14.03.2015


Ответы (2)


Нет, это не гарантируется стандартом. Цитируя все части С++ 14 (n4140) [expr.reinterpret.cast], которые касаются преобразования указателя в целое число, выделено мной:

4 Указатель может быть явно преобразован в любой целочисленный тип, достаточно большой для его хранения. Функция отображения определяется реализацией. [ Примечание. Это должно быть неудивительно для тех, кто знаком со структурой адресации базовой машины. —конец примечания ] ...

5 Значение целочисленного типа или типа перечисления может быть явно преобразовано в указатель. Указатель, преобразованный в целое число достаточного размера (если таковой существует в реализации) и обратно в тот же тип указателя, будет иметь исходное значение; сопоставления между указателями и целыми числами в остальном определяются реализацией. [ Примечание: За исключением случаев, описанных в 3.7.4.3, результатом такого преобразования не будет безопасно полученный указатель. ценность. —конец примечания ]

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

person Angew is no longer proud of SO    schedule 27.04.2015

Я получаю именно эту проблему в библиотеке, экспортирующей указатели на объекты как непрозрачные идентификаторы, и теперь попытки восстановить эти указатели из внешних вызовов не работают для старых процессоров x86 (во времена Windows 98). Таким образом, хотя мы можем ожидать такого поведения, в общем случае это неверно. В 386-CPU адрес состоит из перекрывающихся указателей, поэтому адрес любой позиции памяти не уникален, и я обнаружил, что обратное преобразование не восстанавливает исходное значение.

person Mel Viso Martinez    schedule 06.04.2015