不幸的是,我对strict-aliasing规则和C/C++合法的强制转换后的解引用了解得太晚了。据我所知,下面的代码确实违反了上述规则:
std::byte buffer[sizeof(double)];
double* x = reinterpret_cast<double*>(buffer);
*x = 45.35;
是否允许以下列方式使用std::launder
,
std::byte buffer[sizeof(double)];
double* x = std::launder(reinterpret_cast<double*>(buffer));
*x = 45.35;
这样代码才是正确的?它是如何影响性能的?
那么,在C语言的某些扩展中做一些等价的事情是可能的(不使用联合或memcpy
)?-fno-strict-aliasing
选项是否使这种类型的强制转换更安全?
2条答案
按热度按时间lp0sw83n1#
如果您通过
malloc
、operator new
或类似函数分配了字节数组,则不需要launder
,因为这些操作的结果是指向所创建对象的指针。然而,当直接处理字节数组变量时,需要launder
来到达在该数组中创建的实际对象。然而,这并不会导致对象 exist。而且在C20之前的隐式对象创建中,实际上没有对象存在。所以你的代码只能在C20的规则下工作(这些规则通过缺陷报告追溯到以前的标准,尽管只有更新的编译器才能将它们应用于旧标准下的编译)。
tkclm6bt2#
这段代码很好,没有违反严格的别名规则。它做的完全一样,你可以自由地复制字节到/从字符。