Can I have a real life example when casting through void * works and reinterpret_cast doesn't?

There are a number of questions regarding cross throws (from T1* to unbound T2* ), for example this and this . The answer usually goes like this: reinterpret_cast is implemented, and the conversion to void* , followed by static_cast , is well defined. However, I see no real examples of what might go wrong when reinterpret_cast used.

What are real life examples where casting through void* works, but reinterpret_cast doesn't?

+8
c ++ casting static-cast reinterpret-cast
source share
2 answers

real life examples where casting via void * works and reinterpret_cast doesn’t

If I interpret this sentence in the same way that when running void* works to help me avoid undefined and reinterpret_cast behavior , then the following example is not an example.

reinterpret_cast<TYPE*&> (pointer reference) may violate the strict anti-aliasing rule (this happens, at least for g ++) and will lead you to undefined behavior. Demo

However, static_cast<void*&> will lead to a compiler error and save you from such undefined behavior. Demo

I saw this use in a smart pointer:

 template<class TYPE> struct SmartPointer { void *p; TYPE& operator ++ () { (reinterpret_cast<TYPE*&>(p))++; // breaking strict aliasing rule return *this; } } 
+1
source share

casting from T1 * to unrelated T2 * with reinterpret_cast is no less defined than with static_cast. In fact, when both T1 and T2 are standard layout types, it works the same way (see 5.2.10 / 7):

When prvalue v of type "pointer to T1" is converted to a pointer of type "to cv T2", the result is static_cast <cv T2 *> (static_cast <cv is invalid *> (v))

For custom layout types, the conversion result is not specified, but it is also not set for static_cast.

I assume that you can only get the difference when casting non-index types in such artificial cases:

 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*. }
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*. } 
0
source share

All Articles