我试图了解std::launder
的功能,并且希望通过查找示例实现可以清楚地了解。
我在哪里可以找到std::launder
的示例实现?
当我查看lbic ++时,我看到类似
的代码 template<typename _Tp>
[[nodiscard]] constexpr _Tp*
launder(_Tp* __p) noexcept
{ return __builtin_launder(__p); }
这让我觉得这是那些编译器神奇的功能。
该功能__builtin_launder
可能具有什么作用,它是否只是添加了标记以禁止编译器发出有关别名的警告?
是否可以用std::launder
来理解__builtin_launder
还是仅仅是编译器魔术(钩子)?
答案 0 :(得分:8)
std::launder
的目的不是“抑制警告”,而是消除C ++编译器可能具有的假设。
混淆警告试图告诉您您可能正在执行其行为未由C ++标准定义的行为。
编译器可以并且确实假设您的代码仅在执行标准定义的操作。例如,可以假定一旦构造,指向const
值的指针将不会更改。
编译器可能会使用该假设来跳过从内存中重新获取值(并将其存储在寄存器中),甚至在编译时计算其值并基于该值进行死代码消除。可以假设这一点,因为任何为false的程序都在执行未定义的行为,因此在C ++标准下,任何程序行为都可以接受。
std::launder
旨在允许您获取经过合法修改的真实const
值的指针(例如,通过在其存储中创建一个新对象),并在之后使用该指针 以定义的方式(因此它指向新对象)和其他特定的和类似的情况(不要假定只是“消除别名问题”)进行修改。 __builtin_launder
从某种意义上说将是“无用功”功能,但从另一种意义上来说,它将改变围绕可以生成哪种汇编代码。有了它,就不能对从其输入可以达到什么值的某些假设作出假设。而且某些在输入指针上为UB的代码在输出指针上不是UB。
这是一个专家工具。就我个人而言,如果不做很多标准的研究并仔细检查我没有错误地使用它,就不会使用它。之所以添加它,是因为有人证明某些操作无法以符合标准的方式合理地进行,并且允许库编写者现在高效地进行操作。