Open xmh0511 opened 3 months ago
That's covered by [class.cdtor]/3
That's covered by [class.cdtor]/3
[class.cdtor] is about the lifetime during construction and destruction. In my example, neither is.
That's covered by [class.cdtor]/3
[class.cdtor] is about the lifetime during construction and destruction. In my example, neither is.
You'll notice that nothing in [class.cdtor] actually says that all the rules in that section apply only to objects under construction and destruction. [class.cdtor]/3 applies to all objects that have non-static members. If the construction has not started or the destruction has completed, the behavior is undefined.
That's covered by [class.cdtor]/3
[class.cdtor] is about the lifetime during construction and destruction. In my example, neither is.
You'll notice that nothing in [class.cdtor] actually says that all the rules in that section apply only to objects under construction and destruction. [class.cdtor]/3 applies to all objects that have non-static members. If the construction has not started or the destruction has completed, the behavior is undefined.
[class.cdtor] p3
To form a pointer to (or access the value of) a direct non-static member of an object obj, the construction of obj shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing the member value) results in undefined behavior.
intends to cover the example I gave, however, [basic.life] p6 and p7 says:
For an object under construction or destruction, see [class.cdtor]. Otherwise, such a pointer refers to allocated storage ([basic.stc.dynamic.allocation]), and using the pointer as if the pointer were of type void* is well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in limited ways, as described below. The program has undefined behavior if
In my example, the object is not under construction or destruction, so, it should fall into Otherwise branch.
IIUC the example doesn't match the title because neither ptr->a
nor (*ptr).a
performs access (which is either reading or writing) itself. And... isn't the example just containing well-defined behavior, given A
is a trivial type and the operations after the destruction only refer to a member subobject (see also [class.cdtor] p1)?
IIUC the example doesn't match the title because neither
ptr->a
nor(*ptr).a
performs access (which is either reading or writing) itself. And... isn't the example just containing well-defined behavior, givenA
is a trivial type and the operations after the destruction only refer to a member subobject (see also [class.cdtor] p1)?
struct A{ int a; char b;};
int main(){
A* ptr = new A{0,1};
ptr->~A();
int a = ptr->a; // undefined
int a2 = (*ptr).a; // ??
}
The example should be this, which has access to the int
subobject.
struct A{ int a; char b;}; int main(){ A* ptr = new A{0,1}; ptr->~A(); int a = ptr->a; // undefined int a2 = (*ptr).a; // ?? }
I think current wording already indicates that int a2 = (*ptr).a;
is UB, because a
is not within its lifetime and [basic.life] p7 already covers this. In this case, the glvalue is (*ptr).a
, and we don't need to check whether access via (*ptr)
is well-defined (IMO it's not, see below).
Also, as clarified in cplusplus/draft#4777, it should be clear that when a subobject is accessed. the containing object is also accessed.
Moreover, per the transformation in [expr.ref] p2, when a pointer is used to access a non-static data member or call a non-static member function of the object, the operation is transformed into the form using a glvalue. So IIUC [basic.life] p6.2 is redundant?
Also, as clarified in https://github.com/cplusplus/draft/pull/4777, it should be clear that when a subobject is accessed. the containing object is also accessed.
>:-O
In my example, the object is not under construction or destruction, so, it should fall into Otherwise branch.
The wording here could definitely be improved, but I believe the intent is that if the object is under construction or destruction, then you get the additional permissions in [class.cdtor], but the restrictions in [class.cdtor] apply always.
Full name of submitter (unless configured in github; will be published with the issue): Jim X
[basic.life] p6 says:
However, [basic.life] p7 says:
As said in [basic.life] p7, the behavior of a glvalue should be defined similarly to a pointer in this aspect, however, [basic.life] p7 does not cover when accessing a non-static data member. "the object" in the first bullet presumably means the object the glvalue refers to.
Suggested Resolution
or