[英]How to interpret the precondition of std::launder?
struct X { int n; };
const X *p = new const X{3}; // #1
new (const_cast<X*>(p)) const X{5}; // #2
const int c = std::launder(p)->n;
假设在#1
创建的 object 被命名为obj1
而在#2
创建的 object 被命名为obj2
。 std::launder
的前提是
[ptr.launder] p2链接
p代表memory中一个字节的地址A。 一个在其生命周期内且类型类似于 T 的 object X 位于地址 A。可通过结果访问的所有存储字节都可通过 p 访问(见下文) 。
如果存在 object Z,则可以通过指向 object Y 的指针值访问存储 b 的一个字节,该指针与 Y 可互转换,因此 b 在 Z 占用的存储空间内,或者如果 ZA8CFDE6331BD59EB2AC9C94B 则立即封闭数组 ZA8CFDE6331BD59EB2AC9C94B是一个数组元素。
这个规则有点晦涩。 以下解释是否正确?
obj2
将占用以A
开头的sizeof(X)
字节数。 将Y
( std::launder(p)
指向的 object)和Z
(即obj2
)视为同一个 object,它们是指针可互转换的,并且obj2
占用的sizeof(X)
字节都在Z
之内,因此这些字节都可以通过std::launder(p)
访问。 也就是说,“可以通过结果访问的所有存储字节”。 这些字节是否可以通过p
到达? 假设Y
(即p
指向的 object)和Z
是相同的 object obj1
,它们也是假设数组的数组元素,根据 [basic.compound] p3
一个不是数组元素的类型 T 的 object 被认为属于一个类型为 T 的元素的数组。
由于这些以A
开头的字节都在以Z
为元素的数组中。 因此,我们可以说这些字节都可以通过p
到达?
[basic.compound]/3 不相关。 它特别指出它仅适用于指针算术和比较的目的。 object 实际上不存在数组。
我认为当您调用std::launder
时,相关地址有四个对象: obj1
、 obj1.n
、 obj2
和obj2.n
。 obj1
和obj1.n
是指针可互转换的, obj2
和obj2.n
。 除了相同的对之外的其他组合不是指针可互转换的。 没有数组对象,因此“如果 Z 是数组元素,则为立即封闭的数组 object”。 不相关。
当考虑来自std::launder(p)
的可达性时,它指向obj2
因此只有obj2
和obj2.n
需要在引用中被视为Z
obj2.n
占用obj2
的一个(不适当的)字节子集,因此它不相关。 可到达的字节是obj2
中的字节。 除了我专门考虑obj2.n
之外,这是对您的考虑的重新表述。
通过完全相同的推理,从p
(指向obj1
)可到达的字节都是obj1
中的所有字节。
obj1
和obj2
具有相同的大小,因此占用完全相同的字节。 因此std::launder(p)
不会使任何从p
无法访问的字节都可以访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.