Безопасно ли приводить указатель к целому числу, увеличивать это целое число и возвращать обратно?

Предположим, у меня есть действительный указатель p0:

T a[10];
T* p0 = &a[0];

Я знаю, что я могу безопасно выполнить круговой переход следующим образом:

reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(p0)) == p0;

Но безопасно ли делать следующее?

T* p1 = reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(p0) + sizeof(T));

т.е. могу ли я быть уверен, что нет УБ и что p1 == &a[1]?


person yuri kilochek    schedule 21.05.2015    source источник
comment
Что вы имеете в виду, могу ли я быть уверен, что нет беззнакового байта? Где?   -  person theV0ID    schedule 21.05.2015
comment
@theV0ID UB — популярная в мире C++ аббревиатура Undefined Behavior.   -  person bashrc    schedule 21.05.2015
comment
Я почти уверен, что это не сработает в системах со словарной адресацией, где увеличение адреса на n приводит к тому, что он указывает на n*wordsize байта дальше.   -  person user2357112 supports Monica    schedule 21.05.2015
comment
@theV0ID: неопределенное поведение, а не беззнаковый байт.   -  person user2357112 supports Monica    schedule 21.05.2015
comment
дубликат: stackoverflow.com/questions/22624472/   -  person Thomas B.    schedule 21.05.2015
comment
@LightnessRacesinOrbit: Большое спасибо за этот остроумный комментарий.   -  person theV0ID    schedule 21.05.2015
comment
@theV0ID: вернись :)   -  person Lightness Races in Orbit    schedule 21.05.2015


Ответы (1)


Это поведение, определяемое реализацией. Ваш компилятор должен задокументировать, эквивалентна ли арифметика указателей целочисленной арифметике преобразованных числовых значений указателей. Это должно иметь место на современных компьютерах с «плоским» пространством памяти с байтовой адресацией; но его переносимость на всех платформах не гарантируется.

Использование char* вместо uintptr_t будет переносимым, пока вы остаетесь в пределах массива и убедитесь, что указатель правильно выровнен для T перед преобразованием обратно.

person Mike Seymour    schedule 21.05.2015