cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2860 [basic.life] Remove out-of-sync term "vacuous initialization" #505

Closed frederick-vs-ja closed 1 month ago

frederick-vs-ja commented 7 months ago

Full name of submitter (unless configured in github; will be published with the issue): Jiang An

Reference (section label): [basic.life], [stmt.dcl]

Link to reflector thread (if any):

Issue description:

The current definition of term "vacuous initialization" was established by CWG2256, which predated P0848R3. As of C++20/P0848R3, a class may have a trivial but not eligible default constructor, while default-initialization for a variable of such a class can still call a non-trivial default constructor. Presumably we don't want to say such a variable has vacuous initialization.

E.g. the following example should be ill-formed and implementations seem to agree:

template<int N>
struct ConditionallyTrivial {
  ConditionallyTrivial() requires (N >= 0) = default;
  ConditionallyTrivial() requires (N < 0) {}; // non-trivial
};

int main() {
  goto main_end;
  ConditionallyTrivial<-1> x;
  main_end:;
}

On the other hand, as of CWG2256, the term "vacuous initialization" is only essentially used in [stmt.dcl] and doesn't need to be mentioned in [basic.life]. It seems that we can dissolve the term into [stmt.dcl].

Suggested resolution:

Modify [basic.life] as indicated:

  1. The lifetime of an object or reference is a runtime property of the object or reference. ~A variable is said to have vacuous initialization if it is default-initialized and, if it is of class type or a (possibly multidimensional) array thereof, that class type has a trivial default constructor.~ The lifetime of an object of type T begins when:
    • (1.1) storage with the proper alignment and size for type T is obtained, and
    • (1.2) its initialization (if any) is complete ~(including vacuous initialization)~ ([dcl.init]),

[...]

Modify [stmt.dcl] as indicated:

  1. [...]; unless all such variables ~have vacuous initialization ([basic.life])~ are default-initialized ([dcl.init.general]) and no constructor other than trivial default constructors ([class.default.ctor]) is called in their initialization, the transfer of control shall not be a jump. [...]
t3nsor commented 7 months ago

I think it needs to say something like "unless all such variables are default-initialized and no initialization is performed for any such variable other than calling a trivial default constructor" to exclude zero-initialization either in the context of value-initialization or static initialization.

t3nsor commented 7 months ago

Oh, never mind what I said about static initialization - the rule applies only to automatic storage duration in the first place.

jensmaurer commented 7 months ago

What's wrong with zero-initialization? With the arrival of erroneous values, we will (in general) have some initialization of the bytes regardless, so we might as well accept zero-initialization.

t3nsor commented 7 months ago

There needs to be some way of saying that we can't jump over something like T x {}; assuming this is value-initialization: because value-initialization performs default-initialization, one could say that x is default-initialized.

jensmaurer commented 7 months ago

Ok.

jensmaurer commented 7 months ago

CWG2860

frederick-vs-ja commented 1 month ago

Perhaps should be closed, as CWG2860 is treated as duplicate of CWG2859 which is resolved.