Предположим, у меня есть действительный указатель 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));
то есть я могу быть уверен, что нет UB и что p1 == &a[1]
?
Это поведение, определяемое реализацией. Ваш компилятор должен задокументировать, эквивалентна ли арифметика указателей целочисленной арифметике для преобразованных числовых значений указателей. Это должно иметь место на современных компьютерах с «плоским» адресным пространством памяти; но это не гарантированно работать на всех платформах.
С помощью char*
скорее, чем uintptr_t
будет работать переносимо, пока вы остаетесь в массиве и убедитесь, что указатель правильно выровнен для T
перед преобразованием обратно.