interpret_cast和c样式强制转换是否兼容(按照c++标准)

Is reinterpret_cast and c-style cast compatible (by C++ standard)?

本文关键字:按照 c++ 标准 是否 转换 cast 样式 interpret      更新时间:2023-10-16

C++标准提到reinterpret_cast是实现定义的,除了将(使用reinterpret_cast)强制转换回原始类型将导致原始值首先传递给外,没有提供任何保证。

至少有一些类型的C样式转换的行为方式基本相同-来回转换具有相同值的结果-目前我正在处理枚举和int,但也有一些其他示例。

虽然C++标准为两种类型转换样式都提供了这些定义,但它是否也为混合类型转换提供了相同的保证?如果库X从函数int Y()返回某个enum值,则可以使用上述任何类型转换,而不必担心在Y的体中使用了什么类型转换来将初始enum转换为int?我没有X的源代码,所以我无法检查(而且它可能会随着下一个版本而更改),文档中几乎没有提到类似的事情。

我知道在这种情况下,在大多数实现中,两种类型转换的行为是相同的;我的问题是:C++标准对这种情况有什么看法——如果有的话。

C++根据static_castconst_castreinterpret_cast定义了C转换语法的语义。因此,无论你使用什么语法来实现相同的操作,你都可以得到相同的保证

reinterpret_cast只能用于特定的转换:

  • 指向(足够大)整数的指针,反之亦然
  • 函数指针到函数指针
  • 对象指针到对象指针
  • 指向成员的指针指向成员
  • 要引用的左值表达式

加上(有条件的)函数指针到对象指针,反之亦然。在大多数情况下,转换后的值是未指定的,但可以保证转换后的反向值将产生原始值。

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

C样式转换将根据需要执行static_castreinterpret_cast,然后执行const_cast;所以任何由CCD_ 18定义的转换也由C样式转换定义。

否,reinterpret_cast不是等价于C样式的强制转换。C风格的强制转换允许强制转换reinterpret_cast中不允许的const-variable(因此它包括const_cast的功能)。如果在源类型和目的地类型之间允许static_cast,则它将执行与reinterpret_cast具有不同语义的static_cast。如果不允许转换,它将回退到reinterpret_cast。最后,还有一种情况是,C强制转换不能用任何其他强制转换来表示:它忽略了访问说明符。

举例说明差异:

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
}