gpt4 book ai didi

c++ - std::launder 的目的是什么?

转载 作者:IT老高 更新时间:2023-10-28 11:27:04 57 4
gpt4 key购买 nike

P0137引入了函数模板 std::launder 并在有关 union 、生命周期和指针的部分中对标准进行了许多更改。

本文要解决的问题是什么?我必须注意的语言变化是什么?我们在洗钱做什么?

最佳答案

std::launder 的名称恰如其分,但前提是您知道它的用途。它执行内存清洗

考虑论文中的例子:

struct X { const int n; };
union U { X x; float f; };
...

U u = {{ 1 }};

该语句执行聚合初始化,用 {1} 初始化 U 的第一个成员。

因为 n 是一个 const 变量,编译器可以自由假设 u.x.n 应该 always 为 1 .

如果我们这样做会发生什么:

X *p = new (&u.x) X {2};

因为 X 是微不足道的,我们不需要在创建一个新对象之前销毁旧对象,所以这是完全合法的代码。新对象的 n 成员将为 2。

那么告诉我... u.x.n 会返回什么?

显而易见的答案是 2。但这是错误的,因为允许编译器假定一个真正的 const 变量(不仅仅是一个 const&,而是一个对象变量声明 const) 永远不会改变。但我们只是改变了它。

[basic.life]/8说明可以通过变量/指针/对旧对象的引用访问新创建的对象的情况。并且拥有 const 成员是取消资格的因素之一。

那么……我们怎样才能正确地谈论u.x.n

我们必须洗刷我们的内存:

assert(*std::launder(&u.x.n) == 2); //Will be true.

洗钱用于防止人们追踪您的资金来源。内存清洗用于防止编译器跟踪你从哪里得到你的对象,从而迫使它避免任何可能不再适用的优化。

另一个不合格的因素是如果你改变了对象的类型。 std::launder 也可以在这里提供帮助:

alignas(int) char data[sizeof(int)];
new(&data) int;
int *p = std::launder(reinterpret_cast<int*>(&data));

[basic.life]/8告诉我们,如果在旧对象的存储中分配新对象,则无法通过指向旧对象的指针访问新对象。 launder 让我们能够避开这一点。

关于c++ - std::launder 的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39382501/

57 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com