在哪里可以找到std :: launder真正的功能?

时间:2018-11-12 18:32:00

标签: c++ c++17 reinterpret-cast aliasing

我试图了解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还是仅仅是编译器魔术(钩子)?

1 个答案:

答案 0 :(得分:8)

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

混淆警告试图告诉您您可能正在执行其行为未由C ++标准定义的行为。

编译器可以并且确实假设您的代码仅在执行标准定义的操作。例如,可以假定一旦构造,指向const值的指针将不会更改。

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

std::launder旨在允许您获取经过合法修改的真实const值的指针(例如,通过在其存储中创建一个新对象),并在之后使用该指针 以定义的方式(因此它指向新对象)和其他特定的和类似的情况(不要假定只是“消除别名问题”)进行修改。 __builtin_launder从某种意义上说将是“无用功”功能,但从另一种意义上来说,它将改变围绕可以生成哪种汇编代码。有了它,就不能对从其输入可以达到什么值的某些假设作出假设。而且某些在输入指针上为UB的代码在输出指针上不是UB。

这是一个专家工具。就我个人而言,如果不做很多标准的研究并仔细检查我没有错误地使用它,就不会使用它。之所以添加它,是因为有人证明某些操作无法以符合标准的方式合理地进行,并且允许库编写者现在高效地进行操作。