C++ Logo

std-discussion

Advanced search

Re: About the description of [basic.life]/6

From: Tadeus Prastowo <tadeus.prastowo_at_[hidden]>
Date: Wed, 15 Apr 2020 17:36:34 +0200
On Wed, Apr 15, 2020 at 2:20 AM yo mizu via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> On Wed, Apr 15, 2020 at 2:28 AM Tadeus Prastowo
> <tadeus.prastowo_at_[hidden]> wrote:
> > Quoting [basic.life]/6 with annotations:
[...]
> Thank you for your quick reply.
>
> Before the lifetime of an object has started but after the storage
> which the object will occupy has been allocated 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.
> [Sentence-X]
>
> For an object under construction or destruction, see [class.cdtor].
> [Sentence-Y]
>
> Otherwise, such a pointer refers to allocated storage, and using the
> pointer as if the pointer were of type void*, is well-defined
> [Sentence-A]
>
> Indirection through such a pointer is permitted but the resulting
> lvalue may only be used in limited ways, as described below
> [Sentence-B]
>
> I thought that Sentence-Y and Sentence-A are exclusive and pointers
> that meet the requirements of Sentence-X are classified as either
> Sentence-Y or Sentence-A.

I think Sentence-Y applies when the pointer referred by Sentence-X is
used during an object construction after storage allocation or during
an object destruction before storage reuse/release. The example in
question, however, is not in the context of implementing a
constructor/destructor where it is possible to have a situation where
a storage has already been allocated but the object's lifetime has not
started or an object's lifetime has already ended but the storage has
not been reused/released. So, to understand the example in question,
Sentence-Y can be ignored, leaving only Sentence-X, -A, and -B to be
considered.

On Wed, Apr 15, 2020 at 9:20 AM yo mizu <mizu2594_at_[hidden]> wrote:
>> So you mean, Sentence-X, Sentence-Y and Sentence-A are exclusive?

Sentence-X is futher elaborated in Sentence-Y where Sentence-Y
provides a forward reference, while the pointer defined in Sentence-X
is further elaborated in Sentence-A, -B, and -C where Sentence-A, -B,
and -C provide details and Sentence-C is the one that starts with "The
program has undefined behavior if:" and continues to [basic.life]6.1
up to 6.5.

It is like saying: "Among all cars that are registered at the
municipality of Q, the only car that is registered today is my car
(X). For the cool story, watch channel 7 tonight (Y, a forward
reference). The car is Mazda (A). The car is painted with intricate
symbolisms (B). The car's insurance, however, only covers the
followings: ... (C)".

>> If so, does Sentence-B can be applied to all sentences (X, Y and A),
>> or only to Sentence-A?
>
> I'm sorry for my mistake.
> There was an error, which should be corrected as follows:
> If so, can Sentence-B be applied to all sentences (X, Y and A) ?

Sentence-B elaborates Sentence-X by providing further details.

> I thought "such a pointer" in Sentence-A and Sentence-B means "a
> pointer that meets the requirements of Sentence-X".
> If it's a mistake, what does "such a pointer" mean?

"such a pointer" refers to the pointer defined by Sentence-X to be
"any pointer that represents the address of the storage location where
the object will be or was located".

For the example in question, the pointer `pb' represents the address
of the storage location where the object of type D1 was located,
specifically (as well as correcting my previous comments on your and
Merukun's example programs with respect to object constructions and
destructions) by considering the following quote of the example in
question:

void g() {
  void* p = std::malloc(sizeof(D1) + sizeof(D2));
  B* pb = new (p) D1;

[At this point, `pb' is a pointer that represents the address of an
object of type D1 (the object is already constructed with a default
constructor; previously, I was wrong in thinking that the object had
not been constructed). So, at this point, [basic.life]/6 does not
apply to `pb'.]

  pb->mutate();

[At this point, `pb' is a pointer that represents the address of the
storage location where an object of type D1 was located. So, at this
point, [basic.life]/6 applies to `pb'.]

  *pb; // OK: pb points to valid memory

[The preceding expression is valid owing to [basic.life]/7, which
elaborates Sentence-B.]

  void* q = pb; // OK: pb points to valid memory
  pb->f(); // undefined behavior, lifetime of *pb has ended
}

Is it clear now?

> --
> Best regards,
> yo mizu

-- 
Best regards,
Tadeus

Received on 2020-04-15 10:39:44