C++ Logo

std-discussion

Advanced search

Re: [basic#life-6] unclear what happens if the storage is actually re-used

From: Brian Bi <bbi5291_at_[hidden]>
Date: Tue, 12 Dec 2023 09:59:42 -0500
On Tue, Dec 12, 2023 at 8:20 AM Neil Holmes via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> Hi all,
>
> From [basic#life-6], it is not fully clear what happens when the condition
> is not satisfied. Here is the original text from the standard which defines
> condition when it is still possible to use original pointer in **limited
> cases**.
>
> Before the lifetime of an object has started but after the storage which
> the object will occupy has been allocated22
> <https://eel.is/c++draft/basic#footnote-22> or, after the lifetime of an
> object has ended and before the storage which the object occupied is reused
> or released, any pointer that represents the address of the storage
> location where the object will be or was located may be used but only in
> limited ways. <https://eel.is/c++draft/basic#life-6.sentence-1>
>
> For an object under construction or destruction, see [class.cdtor]
> <https://eel.is/c++draft/class.cdtor>.
> <https://eel.is/c++draft/basic#life-6.sentence-2>
>
> Otherwise, such a pointer refers to allocated storage ([basic.stc.dynamic.
> allocation] <https://eel.is/c++draft/basic#stc.dynamic.allocation>), and
> using the pointer as if the pointer were of type void* is well-defined.
> <https://eel.is/c++draft/basic#life-6.sentence-3>
>
> Indirection through such a pointer is permitted but the resulting lvalue
> may only be used in limited ways, as described below.
> <https://eel.is/c++draft/basic#life-6.sentence-4>
>
> The program has undefined behavior if
>
>
> However it is not clear how the original pointer can be used if the
> condition is not satisfied. I've put an example below where the storage is
> definitely re-used. Does it mean that any use of the original pointer which
> represents the storage is undefined behavior?
>

No, it doesn't mean that "any use" is undefined behavior. [basic.life]/6
implies that *some* uses are well-defined, i.e. "using the pointer as if
the pointer were of type void*" (which unfortunately it doesn't elaborate
on), and gives a list of particular operations that *are* UB.


>
>
> struct B {
> virtual void f();
> void mutate();
> virtual ~B();
> };
>
> struct D1 : B { void f(); };
> struct D2 : B { void f(); };
>
> void B::mutate() {
> new (this) D2; // reuses storage --- ends the lifetime of *this. Does
> it mean that if one uses placement new than first the storage is reused and
> *than* the object's lifetime ends?
> new (this) D2; // NOW STORAGE IS DEFINITELY RE-USED AND THE CONDITION
> in [basic#life-6] is not satisfied
> f(); // undefined behavior
> ... = *this*; // USING THIS IS UNDEFINED BEHAVIOR NOW?
> }
>

> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>


-- 
*Brian Bi*

Received on 2023-12-12 14:59:56