我是否有一个现实生活中的例子,其中通过void *工作并且reinterpret_cast没有?

时间:2011-07-06 10:24:48

标签: c++ casting reinterpret-cast static-cast

有一系列关于交叉投射的问题(从T1*投射到不相关的T2*),例如thisthis。答案通常是这样的:reinterpret_cast是实现定义的,转换为void*后跟static_cast是明确定义的。然而,我没有看到使用reinterpret_cast时可能出现什么问题的真实例子。

通过void*进行投射并且reinterpret_cast无效的现实示例是什么?

2 个答案:

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