reinterpret_cast和c-style强制兼容(按C ++标准)?

时间:2012-11-14 16:56:08

标签: c++ casting reinterpret-cast

C ++标准提到reinterpret_cast是实现定义的,并且除了向原始类型返回(使用reinterpret_cast)将导致原始值传递给第一个之外,不提供任何保证。

至少某些类型的C风格转换的行为方式大致相同 - 使用相同的值来回转换结果 - 目前我正在使用枚举和int s,但还有一些其他示例

虽然C ++标准给出了两种演员风格的定义,但它是否也为混合演员提供了同样的保证?如果库X从函数int Y()返回一些enum值,可以使用上述任何一个强制转换,而不必担心在Y的正文中使用什么强制转换将初始enum转换为int?我没有X的源代码,所以我无法检查(无论如何它都可以随着下一个版本而改变),文档中几乎没有提到这样的东西。

我知道在大多数实现中,在这种情况下,两个强制转换都表现相同;我的问题是:C ++标准对这类案例的评价是什么 - 如果有的话。

3 个答案:

答案 0 :(得分:4)

C ++根据static_castconst_castreinterpret_cast定义C cast语法的语义。因此,无论您使用何种语法来实现相同的操作,都可以获得相同的保证。

答案 1 :(得分:2)

reinterpret_cast只能用于特定转化:

  • 指向(足够大)整数,反向
  • 指向函数指针的函数指针
  • 指向对象指针的对象指针
  • 指向成员的指针指向会员
  • 左值表达式参考

加(有条件地)函数指针指向对象指针并反向。在大多数情况下,转换后的值未指定,但保证转换后跟其反转将产生原始值。

特别是,您不能使用reinterpret_cast在整数和枚举类型之间进行转换;转换必须使用static_cast(或隐式地,在将未范围的枚举转换为整数类型时)完成,这是为足够大的整数类型定义的。唯一可能的问题是,如果图书馆做了一些完全疯狂的事情,例如return reinterpret_cast<int&>(some_enum);

C风格的演员表将执行static_castreinterpret_cast,然后根据需要执行const_cast;所以static_cast定义良好的转换也是由C风格的演员定义的。

答案 2 :(得分:1)

不,reinterpret_cast 等同于C样式广播。 C样式转换允许转换const_cast中不允许的const-volatile(因此它包含reinterpret_cast的功能)。如果源类型和目标类型之间允许static_cast,则它将执行static_cast,其语义与reinterpret_cast不同。它不允许转换,它将回退到reinterpret_cast。最后有一个角落案例,其中C cast无法用任何其他演员表示:它忽略了访问说明符。

一些说明差异的例子:

class b0 { int a; };
class b1 { int b; };
class b2 { int c; };
class d : public b0, public b1, b2 {};
int main() {
   d x;
   assert( static_cast<b1*>(&x) == (b1*)&x );
   assert( reinterpret_cast<b1*>(&x) != (b1*)&x ); // Different value
   assert( reinterpret_cast<b2*>(&x) != (b2*)&x ); // Different value, 
                                                   // cannot be done with static_cast
   const d *p = &x;
   // reinterpret_cast<b0*>(p);                    // Error cannot cast const away
   (b0*)p;                                         // C style can
}