C ++标准提到reinterpret_cast
是实现定义的,并且除了向原始类型返回(使用reinterpret_cast
)将导致原始值传递给第一个之外,不提供任何保证。
至少某些类型的C风格转换的行为方式大致相同 - 使用相同的值来回转换结果 - 目前我正在使用枚举和int
s,但还有一些其他示例
虽然C ++标准给出了两种演员风格的定义,但它是否也为混合演员提供了同样的保证?如果库X从函数int Y()
返回一些enum
值,可以使用上述任何一个强制转换,而不必担心在Y的正文中使用什么强制转换将初始enum
转换为int
?我没有X的源代码,所以我无法检查(无论如何它都可以随着下一个版本而改变),文档中几乎没有提到这样的东西。
我知道在大多数实现中,在这种情况下,两个强制转换都表现相同;我的问题是:C ++标准对这类案例的评价是什么 - 如果有的话。
答案 0 :(得分:4)
C ++根据static_cast
,const_cast
和reinterpret_cast
定义C cast语法的语义。因此,无论您使用何种语法来实现相同的操作,都可以获得相同的保证。
答案 1 :(得分:2)
reinterpret_cast
只能用于特定转化:
加(有条件地)函数指针指向对象指针并反向。在大多数情况下,转换后的值未指定,但保证转换后跟其反转将产生原始值。
特别是,您不能使用reinterpret_cast
在整数和枚举类型之间进行转换;转换必须使用static_cast
(或隐式地,在将未范围的枚举转换为整数类型时)完成,这是为足够大的整数类型定义的。唯一可能的问题是,如果图书馆做了一些完全疯狂的事情,例如return reinterpret_cast<int&>(some_enum);
C风格的演员表将执行static_cast
或reinterpret_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
}