Небезопасно смешивать статические и реинтерпрет-литые при бросании в void и обратно?
Просто: Если я static_cast
тип X*
- void*
, всегда ли безопасно reinterpret_cast
вернуть его в X *?
Я не могу выполнить какой-либо случай, если это не удается, например:
#include <iostream>
struct a
{
int* m_array;
};
int main()
{
bool fail = false;
for(int i = 0; ++i < 5000;)
{
a* pA = new a;
pA->m_array = new int [i+1]; // A new size of data everytime
pA->m_array[i] = 10;
void* pvA = static_cast<void*>(pA);
pA = reinterpret_cast<a*>(pvA);
if(pA->m_array[i] != 10)
{
fail = true;
break;
}
delete []pA->m_array;
delete pA;
}
if(fail)
std::cout<<"FAILED!!";
else
std::cout<<"Never failed :/";
}
Ссылка на скомпилированный пример
Дает результат "Никогда не сработал:/" в обоих режимах отладки и выпуска с vs 2012. Однако это, скорее всего, поведение undefined. Правильно?
Ответы
Ответ 1
Он четко определен. Согласно ISO/IEC 14882: 2011 [expr.reinterpret.cast] §7 (основное внимание):
Указатель объекта может быть явно преобразован в указатель объекта другой тип. Когда prvalue v типа "указатель на T1" является преобразованный в тип "указатель на cv T2", результатом является static_cast < cv T2 * > (static_cast < cv void * > (v)), если оба T1 и T2 являются стандартными макетами типы (3.9) и требования к выравниванию T2 не являются более строгими, чем те из T1, или если любой тип недействителен.