开发者

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

开发者 https://www.devze.com 2023-03-18 03:49 出处:网络
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 implemen

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*.
}

0

精彩评论

暂无评论...
验证码 换一张
取 消