2012-11-14 44 views
0

C++标准提到reinterpret_cast是定义执行,并没有给出任何保证不同的是浇铸背面(使用reinterpret_cast)到原始类型将导致传递给第一原始值。reinterpret_cast和c-style cast是否兼容(通过C++标准)?

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

虽然C++标准给出了两个铸风格的定义,它也给混合管型相同的质量保证?如果库X从函数int Y()中返回一些enum的值,可以使用上述任何一种类型,而不必担心在Y的身体中将初始enum转换为int的投射是什么?我没有X的源代码,所以我无法检查(无论如何,它可能会随着下一个版本发生变化),文档中几乎没有提到类似的东西。

我知道,在在这样的情况下,两个大多数实现投射相同的行为;我的问题是:C++标准对这种情况有什么看法 - 如果有的话。

+0

Ç铸造来回并不总是导致相同的值...'(浮动)((INT)3.141)'不会给我'3.141 '回来。 – Xymostech

+0

您可以使用'static_cast'在ints和enums之间进行转换。 –

+0

@Xymostech我的意思是只有在C风格演员下才能正常工作的类型。我知道在某些情况下C风格的铸造会改变数值,但对于这些情况,整个问题都是没有意义的。 –

回答

4

C++根据static_cast,const_castreinterpret_cast定义了C语言转换语法的语义。所以,无论使用哪种语法来实现它,您都可以获得相同的操作保证。

2

reinterpret_cast只能用于特定的转化:

  • 指针(足够大的)整数,而反向
  • 函数指针为一个函数指针
  • 对象指针为一个对象指针
  • 指针到成员指针
  • 左值表达为参考

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

特别是,您不能使用reinterpret_cast在整数和枚举类型之间进行转换;必须使用static_cast(或隐式地将非范围枚举转换为整数类型时)完成转换,该转换为足够大的整数类型定义良好。唯一可能的问题是,如果库中没有的东西完全疯狂如return reinterpret_cast<int&>(some_enum);

A C样式转换将执行无论是static_castreinterpret_cast,随后const_cast,都是必要的;所以任何由static_cast定义明确的转换也可以通过C风格演员明确定义。

1

不,reinterpret_cast不是相当于C风格演员。 C风格转换允许在reinterpret_cast中不允许抛出const volatile(因此它包含const_cast的功能)。如果在源和目标类型之间允许static_cast,它将执行与reinterpret_cast具有不同语义的static_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 
} 
+0

还有'const_cast',所以你注释掉的错误可以使用它“修复”。无论如何,我认为你误会了我。我的问题不是如果这些可以在给定的代码行中进行交换,而是如果通过其中的一种(例如C风格)将值转换为另一种类型,则在使用另一种类型转换为原始类型时保证赋予相同的值(任何'_cast' C++运算符)。 –

+0

@j_kubik:我理解了这个问题,也许我在答案中不清楚。 'reinterpret_cast'是**不等同于C cast,也不等同于'static_cast'或'const_cast'。在它们相等的情况下,可以应用反演,在其他一些情况下,反演也可以是隐式的,但是**不能盲目地为我提供的示例盲目地执行reinterpret_cast'(特别是第二个这个问题:*我可以退后一步忽略原始演员是什么吗?*答案是**否,你不能** –

+0

如果我知道一些不透明的libX之间铸造的原始类型和流行类型,那么我知道他们使用了什么类型的演员:C风格以可预测的方式工作,并且你上面提到的限制了他们使用'_cast'强制转换的自由,通常只剩下一个选项(只在leas之一,在指针之间可以'reinterpret_cast'是可能的但通常只有在static_cast不可用的情况下才会使用)清除后,我想知道是否可以在不知道以上哪两个被使用的情况下回退。已知类型 –