8

有一组关于交叉转换(从转换T1*到不相关T2*)的问题,例如thisthis。答案通常是这样的:reinterpret_cast是实现定义的,并且转换到void*后面static_cast是明确定义的。然而,我还没有看到任何真实的例子说明reinterpret_cast使用时会出现什么问题。

有哪些现实生活中的例子可以通过void*有效而reinterpret_cast无效?

4

2 回答 2

1

通过 void* 进行投射而 reinterpret_cast 不起作用的真实示例

如果我将这句话解释为,通过强制转换void*可以帮助我避免未定义的行为并且reinterpret_cast没有,那么下面就是一个例子。

reinterpret_cast<TYPE*&>(指针引用)可能会破坏严格的别名规则(至少发生在 g++ 中)并导致您出现未定义的行为。演示

但是,static_cast<void*&>会导致编译器错误并使您免于这种未定义的行为。演示

我在智能指针中看到过这样的用法:

template<class TYPE>
struct SmartPointer
{
  void *p;
  TYPE& operator ++ ()
  {
    (reinterpret_cast<TYPE*&>(p))++;  // breaking strict aliasing rule
    return *this;
  }
}
于 2011-07-06T10:41:24.587 回答
0

使用 reinterpret_cast 从 T1* 转换到不相关的 T2* 的定义并不比使用 static_cast 少。实际上,当 T1 和 T2 都是标准布局类型时,它的工作方式相同(参见 5.2.10/7):

当“指向 T1 的指针”类型的纯右值 v 转换为“指向 cv T2 的指针”类型时,结果为 static_cast<cv T2*>(static_cast<cv void*>(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*.
}

于 2011-07-06T11:02:56.793 回答