C++ Logo

std-discussion

Advanced search

Re: when to std::launder

From: Nicolas Lesser <blitzrakete_at_[hidden]>
Date: Mon, 29 Apr 2019 14:14:22 +0200
char buffer[sizeof(C)]; is not reassignable.

On Mon, Apr 29, 2019, 12:07 PM Mohamed Khaled <mkmostafa92_at_[hidden]> wrote:

> what does "and/or not reassignable buffer" mean?
>
> On Mon, Apr 29, 2019 at 11:54 AM Nicolas Lesser <blitzrakete_at_[hidden]>
> wrote:
>
>> Mohamed Khaled via Std-Discussion wrote:
>> > Hello All,
>> >
>> > ```
>> > #include <memory>
>> > #include <iostream>
>> >
>> > struct C
>> > {
>> > const int x;
>> > };
>> >
>> > void foo1()
>> > {
>> > C c{1};
>> > c.~C();
>> > new (&c) C{2};
>> > std::cout << c.x << std::endl;
>> > }
>> >
>> > std::unique_ptr<C> foo2_a()
>> > {
>> > std::unique_ptr<C> c(new C{1});
>> > c->~C();
>> > new (c.get()) C{2};
>> > return c;
>> > }
>> >
>> > void foo2_b(std::unique_ptr<C> c)
>> > {
>> > std::cout << c->x << std::endl;
>> > }
>> >
>> > int main()
>> > {
>> > foo1();
>> > foo2_b(foo2_a());
>> > }
>> > ```
>> >
>> > As far as I understand, in foo1() one should invoke std::launder
>> whenever c
>> > is being accessed after the placement. Should it also be invoked in
>> foo2_b,
>> > that is when the access to the object whose memory is being reused is in
>> > some separate function rather than the one where the placement happened.
>>
>> std::launder is used only when you only have access to the new element
>> through the old object, when for example the class has a const data member.
>> In your case, you are right that in foo1 you should use std::launder. This
>> *also* applies to foo2_b, since the pointer stored in the unique_ptr points
>> to the old object and it can only be used to access the new object with
>> std::launder.
>>
>> > More generally should the placement new always be coupled with
>> std::launder?
>>
>> Not necessarely, only when you are using placement new on a variable
>> and/or not reassignable buffer. If you use a pointer for example you can do
>> this:
>>
>> ptr = new (ptr) C{2};
>>
>> And there you don't have to use placement new.
>>
>> --
>> - Nicolas
>>
>

Received on 2019-04-29 07:16:24