2

我试图了解是什么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只是更多的编译器魔法(钩子)?

4

1 回答 1

13

的目的std::launder不是“抑制警告”,而是消除 C++ 编译器可能具有的假设。

别名警告试图通知您您可能正在做的事情其行为未由 C++ 标准定义。

编译器可以并且确实假设您的代码仅执行标准定义的事情。例如,它可以假设指向一个const值的指针一旦构造就不会改变。

编译器可能会使用该假设跳过从内存中重新获取值(并将其存储在寄存器中),甚至在编译时计算其值并基于它进行死代码消除。它可以假设这一点,因为它为假的任何程序都在执行未定义的行为,因此任何程序行为都在 C++ 标准下被接受。

std::launder经过精心设计,您可以将指针指向const经过合法修改的真正值(例如,通过在其存储中创建新对象)并在修改后以定义的方式使用该指针因此它引用新对象)和其他特定和类似的情况(不要假设它只是“消除混叠问题”)。 __builtin_launder从某种意义上说,它将是一个“noop”函数,但从另一种意义上说,它将改变围绕它生成什么样的汇编代码。有了它,就不能对其输出做出关于可以从其输入中获得什么价值的某些假设。一些输入指针上的 UB 代码不是输出指针上的 UB。

它是一个专家工具。我个人不会在没有进行大量标准研究和仔细检查我没有用错的情况下使用它。添加它是因为有人证明某些操作无法以符合标准的方式合理地执行,并且它允许库编写者现在有效地执行此操作。

于 2018-11-12T19:40:09.957 回答