问题标签 [stdlaunder]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 执行算术时也需要 std::launder 吗?
的前提条件之一是std::launder
要求对象在其生命周期内。我认为这是能够取消引用元素的必要条件。这是否意味着,如果我获得指向数组元素的指针,那么如果我只执行算术,则不需要洗钱?还是只是UB?
一个清晰的代码示例。在代码的注释中做了一些澄清问题的评论。
c++ - 为什么这里需要 std::launder ?
我正在阅读 cppreference 并且在std::aligned_storage的示例中有一个向量/数组类的示例:
本质上,每个元素所在的每个存储桶/区域/内存地址都是一个字符缓冲区。在存在的每个元素位置,都会在 T 类型的缓冲区中完成新的放置。因此,当返回该缓冲区的位置时,可以将 char 缓冲区转换为 T*,因为在那里构造了一个 T。为什么从 C++17 开始需要 std::launder?我已经问了很多关于这个的问题,似乎同意:
这显然不是严格的混叠违规,完全没问题。那么为什么这里需要 std::launder 呢?
c++ - 我可以通过placement-new 覆盖一个const 对象吗?
Basic.life/8告诉我们,我们可以使用对象占用的存储空间在其生命周期结束后创建一个新对象,并使用其原始名称来引用它,除非:
- 原始对象的类型不是 const 限定的,如果是类类型,则不包含任何类型为 const 限定或引用类型的非静态数据成员,并且 [...]
强调我的
但是,就在下面,我们可以看到一条注释说:
- 如果不满足这些条件,则可以从表示其存储地址的指针中获取指向新对象的指针,方法是调用
std::launder
这解释了std::launder
. 我们可以有一个具有const
成员的类类型,并使用placement-new 在其中创建一个具有不同内部值的新对象。
令我惊讶的是第一句话的第一部分。它清楚地表明,如果存储是const
(不一定包含const
成员,但整个对象被声明为const
),我们不能使用它来按原样引用新对象,但它可能暗示std::launder
可以修复它。
但是我们如何创建这样的对象呢?最简单的例子失败了:
这是因为我们不能const void*
用作placement-new 的缓冲区。我们可以const_cast
做到,但抛弃“真实”const
是未定义的行为。我相信这里也是如此。
我会理解是否只是禁止使用const
对象作为放置新缓冲区,但如果是这样的话,第一个引号的强调部分的目的是什么?我们可以为不同的对象重用一个真正const
对象的存储吗?
c++ - std::launder 的效果是否在调用它的表达式之后持续?
考虑以下示例代码:
fun
根据语言标准打印什么功能?换句话说,std::launder
last 的效果是否超出了调用它的表达式?或者,我们std::launder
每次需要访问更新的值时都必须使用u.x.n
?
c++ - 如何解释 std::launder 的前提条件?
假设在 处创建的对象#1
是命名obj1
的,而在 处创建的对象#2
是命名的obj2
。的前提std::launder
是
[ptr.launder] p2链接
p 表示内存中一个字节的地址 A。一个在其生命周期内且类型与 T 相似的对象 X 位于地址 A。通过结果可访问的所有存储字节都可通过 p 访问(见下文)。
如果存在对象 Z,则可以通过指向对象 Y 的指针值访问存储 b 的字节,与 Y 可互转换的指针,这样 b 位于 Z 占用的存储空间内,或者如果 Z 位于立即封闭的数组对象内是一个数组元素。
这个规则有点晦涩。以下解释是否正确?
obj2
将占用以 .sizeof(X)
开头的字节数A
。将Y
(指向的对象std::launder(p)
) 和Z
(即obj2
) 视为同一个对象,它们是指针可互转换的,并且它们所sizeof(X)
占用的字节obj2
都在 内Z
,因此这些字节都可以通过 到达std::launder(p)
。也就是说,“可以通过结果访问的所有存储字节”。这些字节是否可以通过p
?假设Y
(即p
指向的对象) 和Z
是同一个对象obj1
,它们也是假设数组的数组元素,根据 [basic.compound] p3
不是数组元素的 T 类型对象被认为属于具有一个 T 类型元素的数组。
由于这些以开头的字节A
都在数组中,其中数组Z
是一个元素。因此,我们可以说这些字节都可以通过p
?
c++ - std::launder vs 放置-新的可达性条件
std::launder
有一个先决条件,即从将要返回的指针可到达的所有字节都可以通过传递的指针到达。
我的理解是,这是为了允许编译器优化,例如
可以优化为始终返回2
。(请参阅指针互转换性与具有相同地址和可以使用 std::launder 将对象指针转换为其封闭数组指针吗?)
这是否意味着可达性前提条件也应该适用于placement-new?否则有什么阻止我写f
如下?:
的地址与 的地址a.a[0]
相同,a
并且新A
对象可以透明地替换为旧A
对象,因此a.b
ing
现在应该是0
。