There's a set of questions regarding c开发者_StackOverflow中文版ross-casts (cast from T1*
to unrelated T2*
), for example this and this. The answer usually goes like this: reinterpret_cast
is implementation defined and conversion to void*
followed by static_cast
is well-defined. Yet I haven't see any real examples of what can go wrong when reinterpret_cast
is used.
What are real-life examples where casting through void*
works and reinterpret_cast
doesn't?
real-life examples where casting through void* works and reinterpret_cast doesn't
If I interpret this sentence as, casting through void*
works to help me avoid undefined behavior and reinterpret_cast
doesn't then following is an example.
reinterpret_cast<TYPE*&>
(pointer reference) may break strict aliasing rule (it happens for g++ at least) and leads you to an undefined behavior. Demo.
However, static_cast<void*&>
will result in compiler error and save you from such undefined behavior. Demo.
I have seen such use in a smart pointer:
template<class TYPE>
struct SmartPointer
{
void *p;
TYPE& operator ++ ()
{
(reinterpret_cast<TYPE*&>(p))++; // breaking strict aliasing rule
return *this;
}
}
casting from T1* to unrelated T2* with reinterpret_cast is not less defined than with static_cast. Actually, when both T1 and T2 are standard layout types it works the same (see 5.2.10/7):
When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast<cv T2*>(static_cast<cv void*>(v))
For non-standard layout types the result of conversion is unspecified, but it's unspecified for static_cast as well.
I guess, you can get a difference only when casting non-pointer types in artificial cases like this:
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*.
}
精彩评论