C++ 20 bit_cast vs reinterpret_cast

bog*_*ose 14 c++ language-lawyer type-alias c++20

根据ISO C++ Commitee的最后一次会议,将在C++ 20标准中引入bit-cast.

我知道reinterpret_cast由于类型合规规则不适合这项工作,但我的问题是为什么他们选择不延伸reinterpret_cast处理对象,比如它的位序列表示,并且更倾向于将此功能作为一种新的语言结构?

Nic*_*las 17

嗯,有一个明显的原因:因为它不能做所有的事情bit_cast.即使在我们可以在编译时分配内存的C++ 20世界中,reinterpret_cast也禁止在constexpr函数中使用.其中一个明确的目标bit_cast是能够在编译时执行这些操作:

此外,目前不可能实现constexpr比特转换功能,因为memcpy它本身不是constexpr.将建议的函数标记为constexpr不需要或阻止memcpy变为constexpr,但需要编译器支持.这使得实现可以自由使用他们自己的内部解决方案(例如,LLVM具有bitcast操作码).

现在,您可以说您可以将此特定用法扩展reinterpret_castconstexpr上下文.但这使得规则变得复杂.您必须记住不能使用的特定形式,而不是简单地知道reinterpret_castconstexpr代码期间reinterpret_cast不能使用它.

此外,还有实际问题.即使你想去reinterpret_cast路线,std::bit_cast也是一个图书馆功能.通过委员会获得库功能总是比语言功能更容易,即使它会获得一些编译器支持.

然后是更主观的东西.reinterpret_cast通常被认为是一种固有的危险操作,表明以某种方式"欺骗"类型系统.相比之下,bit_cast不是.它正在生成一个新对象,就好像通过从现有对象复制其值表示一样.它是一个低级工具,但它不是一个与类型系统混淆的工具.因此,拼写"安全"操作与拼写"危险"操作的方式相同会很奇怪.

事实上,如果你以同样的方式拼写它们,它会开始提出一个问题,为什么这个定义得相当明确:

float f = 20.4f;
int i = reinterpret_cast<int>(f);
Run Code Online (Sandbox Code Playgroud)

但这有点不好:

float f = 20.4f;
int &i = reinterpret_cast<int &>(f);
Run Code Online (Sandbox Code Playgroud)

当然,语言律师或熟悉严格别名规则的人会理解为什么后者是坏的.但对于非专业人士来说,如果用它reinterpret_cast来进行位转换是很好的,那么reinterpret_cast用于转换指针/引用并将现有对象解释为转换类型的原因尚不清楚.

不同的工具应拼写不同.