有一系列关于交叉投射的问题(从T1*
投射到不相关的T2*
),例如this和this。答案通常是这样的:reinterpret_cast
是实现定义的,转换为void*
后跟static_cast
是明确定义的。然而,我没有看到使用reinterpret_cast
时可能出现什么问题的真实例子。
通过void*
进行投射并且reinterpret_cast
无效的现实示例是什么?
答案 0 :(得分:1)
铸造的现实例子 通过无效*工作和 reinterpret_cast没有
如果我将这句话解释为,通过void*
投射以帮助我避免未定义的行为,而reinterpret_cast
则不是以下示例。
reinterpret_cast<TYPE*&>
(指针引用)可能会破坏严格的别名规则(它至少会发生在g ++中)并导致您出现未定义的行为。 Demo
但是,static_cast<void*&>
将导致编译器错误并使您免于此类未定义的行为。 Demo
我在智能指针中看到了这样的用法:
template<class TYPE>
struct SmartPointer
{
void *p;
TYPE& operator ++ ()
{
(reinterpret_cast<TYPE*&>(p))++; // breaking strict aliasing rule
return *this;
}
}
答案 1 :(得分:0)
使用reinterpret_cast从T1 *转换为不相关的T2 *与static_cast的定义相同。实际上,当T1和T2都是标准布局类型时,它的工作原理相同(见5.2.10 / 7):
当prvalue v类型为“指向 T1“被转换为类型”指针 到cv T2“,结果是 static_cast&lt; cv T2 *&gt;(static_cast&lt; cv 无效*&GT;(v))中
对于非标准布局类型,未指定转换结果,但也未指定static_cast。
我想,只有在人工案例中投射非指针类型时才能获得差异:
struct Foo
{
};
struct Bar
{
operator void*()
{
return 0;
}
};
int main ()
{
Bar b;
Foo * p1 = static_cast<Foo*>(static_cast<void *>(b)); // ok, Bar::operator void* -> static_cast
Foo * p2 = reinterpret_cast<Foo*>(b); // error, no conversion from Bar to Foo*.
}