This also means, `x.i == 5` is invalid even if in c++17. Because such a `newly created subobject` does not satisfy that it will be created in the storage  after the lifetime of an object has ended and before the storage which the object occupied is reused or released.
Maybe this condition is a defect. Or, the intent of the standard indeed means this. So, for your example  `x.i == 5;`, whether `x.i` is required to launder or not, is determined by the condition, irrelevant of these conditions listed in the below.   

However, Please note the last sentence in the document [basic.life], it is:  
>
In this subclause, “before” and “after” refer to the “happens before” relation ([intro.multithread]).
 
[Note: 
Therefore, undefined behavior results if an object that is being constructed in one thread is referenced from another thread without adequate synchronization.
 
— end note]. 

So, these rules intend to cover the multithread situations. So, my reading is, `after the lifetime of an object has ended` means that call destructor  explicitly or reuse the storage occupied by the object, which would end the lifetime of such an object. And `before the storage which the object occupied is reused or released.` means that in other threads, there's no such operation that will occupy the storage or release the storage. That will make sense.

jim x <xmh970252187@gmail.com> 于2020年9月11日周五 下午12:00写道:
From the condition, I agree with this opinion. And the example that follows the rule [basic.life#8] evidences this opinion. that is, call destructor `this->~C();` explicitly. However, I argue here, is that, this condition will contradict with [intro.object#2], that means, the new created subobject would never be accessed by the original name which refers to the subobject.  

John Mousseau <jhnmou20@gmail.com> 于2020年9月11日周五 上午6:33写道:
In your example, the whole struct is replaced, so that the condition is easily fulfilled by the old and new S object both being complete objects, and the part with p1 and p2 isn't required, I think.
In my example, however, only a subobject is replaced. After some consideration, I think jim x is probably right that they can be the same. It would be weird if such a simple replacement wasn't intended to be defined anymore, when it worked in c++17. However, I think some consideration should be given to the beginning of [basic.life]/8 in general. Strictly speaking, it describes the situation in which such a replacement is possible as:
"If, after the lifetime of an object has ended and before the storagewhich the object occupied is reused or released, a new object is created at the storage location which the original object occupied."

But technically, the lifetime of the old object was only ended *because* its storage was reused. It could be interpreted in such a way that it is required to explicitly end the lifetime of the old object (by calling a destructor) before the placement-new expression. I saw an SO post in which a pretty reputable user interpreted it in this way and inferred the following?

struct X {int i; float j;} x;
int& ir = x.i;
x.~X();
new (&x) X{};
bool b = ir == 5; // well-defined
new (&x) X{};
b = ir == 5; // undefiend because lifetime of X  wasn't ended so basic.life/8 doesn't apply.

Is this a sensible interpretation? If that was true than it might not be possible to replace non-class objects at all. (Unless the psedo-destructor ends their lifetime? :/ )



Am Do., 10. Sept. 2020 um 12:30 Uhr schrieb <language.lawyer@gmail.com>:
I think, p1 p2 must be the old and the new objects, they can't be the same object.
I assume p1 and p2 are needed for the following code:

struct S { int i; };

S s {};
int& ri = s.i;

new (&s) S {};


where the wording guarantees that `ri` will refer to the new int subobject (o2) of the object of type S (p2)


On 10/09/2020 12:43, jim x via Std-Discussion wrote:
> I think your first opinion is the intent of the rule.  Because, according
> to the rule [intro.object#2] <https://eel.is/c++draft/intro.object#2>,  the
> new object has became the subobject of the object X, and the condition "o1
> and o2 are direct subobjects of objects P1 and P2" is true. The standard
> does not say `P1` and `P2` shall not be the same object, the object
> `X` itself satisfies all rules listed in [basic.life#8]
> <https://eel.is/c++draft/basic.life#8>. So, there's no necessary to use
> `std::launder`.
>
> John Mousseau via Std-Discussion <std-discussion@lists.isocpp.org>
> 于2020年9月9日周三 上午1:49写道:
>
>> Dear list members,
>>
>> in draft N4860 <https://isocpp.org/files/papers/N4860.pdf>, which I
>> assume is close to C++20, the wording of [basic.life]/8 differs from C++17
>> in that the notion of "transparently replaceable" was involved. I am
>> wondering whether condition 8.5 of that paragraph allows for p1 and p2 to
>> be the same object.
>>
>> Consider the following most trivial example:
>>
>>      struct X {int i; float f;};
>>      X x{3, 3.f};
>>      new(&x.i) int(5);
>>      // x.i == 5 without launder? True in C++17.
>>
>> According to C++17's wording this is surely the case as there is no
>> const-qualification involved at all. However, in the newest wording, while
>> conditions (8.1) through (8.4) are fulfilled (for o1 and o2 being the old
>> and new int respectively), condition (8.5) might be unfulfilled, as neither
>> are both objects complete, nor are they subobjects of (different) objects
>> p1 and p2, unless, by [intro.object]/2, the new int becomes a subobject of
>> x, and when then consider p1 and p2 of [basic.life]/8.5 to be identical. If
>> we then consider x to be transparently-replaceable by itself, the condition
>> would be fulfilled. Is that the intended interpretation or is the intention
>> that the access in my example now requires std::launder even though no
>> constness is involved?
>>
>> Sorry in case I am not seeing the obvious and thank you for your time.
>>
>> Best Regards
>> John Mousseau
>> --
>> Std-Discussion mailing list
>> Std-Discussion@lists.isocpp.org
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
>
>

Am Do., 10. Sept. 2020 um 12:30 Uhr schrieb <language.lawyer@gmail.com>:
I think, p1 p2 must be the old and the new objects, they can't be the same object.
I assume p1 and p2 are needed for the following code:

struct S { int i; };

S s {};
int& ri = s.i;

new (&s) S {};


where the wording guarantees that `ri` will refer to the new int subobject (o2) of the object of type S (p2)


On 10/09/2020 12:43, jim x via Std-Discussion wrote:
> I think your first opinion is the intent of the rule.  Because, according
> to the rule [intro.object#2] <https://eel.is/c++draft/intro.object#2>,  the
> new object has became the subobject of the object X, and the condition "o1
> and o2 are direct subobjects of objects P1 and P2" is true. The standard
> does not say `P1` and `P2` shall not be the same object, the object
> `X` itself satisfies all rules listed in [basic.life#8]
> <https://eel.is/c++draft/basic.life#8>. So, there's no necessary to use
> `std::launder`.
>
> John Mousseau via Std-Discussion <std-discussion@lists.isocpp.org>
> 于2020年9月9日周三 上午1:49写道:
>
>> Dear list members,
>>
>> in draft N4860 <https://isocpp.org/files/papers/N4860.pdf>, which I
>> assume is close to C++20, the wording of [basic.life]/8 differs from C++17
>> in that the notion of "transparently replaceable" was involved. I am
>> wondering whether condition 8.5 of that paragraph allows for p1 and p2 to
>> be the same object.
>>
>> Consider the following most trivial example:
>>
>>      struct X {int i; float f;};
>>      X x{3, 3.f};
>>      new(&x.i) int(5);
>>      // x.i == 5 without launder? True in C++17.
>>
>> According to C++17's wording this is surely the case as there is no
>> const-qualification involved at all. However, in the newest wording, while
>> conditions (8.1) through (8.4) are fulfilled (for o1 and o2 being the old
>> and new int respectively), condition (8.5) might be unfulfilled, as neither
>> are both objects complete, nor are they subobjects of (different) objects
>> p1 and p2, unless, by [intro.object]/2, the new int becomes a subobject of
>> x, and when then consider p1 and p2 of [basic.life]/8.5 to be identical. If
>> we then consider x to be transparently-replaceable by itself, the condition
>> would be fulfilled. Is that the intended interpretation or is the intention
>> that the access in my example now requires std::launder even though no
>> constness is involved?
>>
>> Sorry in case I am not seeing the obvious and thank you for your time.
>>
>> Best Regards
>> John Mousseau
>> --
>> Std-Discussion mailing list
>> Std-Discussion@lists.isocpp.org
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
>
>