Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++20 "transparently replaceable" relation

In the final working draft of C++20 (and the newest publicly available draft linked below), the wording of [basic.life] has been changed regarding how objects are allowed to replace other objects, so that pointers, references and the object's name automatically refer to the new object. For this purpose the relation "transparently replaceable" is introduced. However, I'm not sure if I'm understanding this correctly. Consider this example:

struct X {int a = 3; float b;};
X x;
new(&x.a) int(5);
x.a == 5 // true without std::launder?

In C++17 this was certainly true, as the old int was neither a const object nor class with const non-static members.

Now, however, the new transparently replaceable relation might not allow this anymore. When considering the relation for the old and new int object, conditions (8.1) through (8.4) are fulfilled, but what about condition (8.5)?

either o1 (the old int) and o2 (the new int) are both complete objects (the old int was definitely a subobject, so this part is false) or o1 and o2 are direct subobjects of objects p1 and p2, respectively, and p1 is transparently replaceable by p2.

Is the new int a complete object, because it was constructed "on its own" (we placed only a new int not a new X)?

Or can it be argued that because of the wording of [intro.object]\2 the new int is a subobject of x, just like the old int, (i highly suspect that this is the intended interpretation, tbh) and therefore x fulfills both the role of p1 and p2 in the definition and is x then "transparently replaceable" with itself, meaning that (8.5) is fulfilled?

Or is the intent that this now requires std::launder even though nothing const-qualified is involved?

like image 222
JMC Avatar asked Sep 08 '20 13:09

JMC


1 Answers

[intro.object]p2 applies regardless of whether [basic.life]p8 applies, so o1 and o2 are direct subobjects of the same object. You can easily check that an object is always transparently replaceable by itself, so p1 transparently replaces p2, so o1 transparently replaces o2.

This is in line with the intent, which was to narrowly address national body comment US041 on the C++20 Committee Draft. Specifically, in the case where [intro.object]p2 does not apply (for example, because the replaced object is a base class subobject rather than an array element or member subobject), you can no longer access the newly-created (complete) object as if it were a subobject of another object.

like image 149
Richard Smith Avatar answered Sep 27 '22 19:09

Richard Smith