Description
Full name of submitter (unless configured in github; will be published with the issue): Richard Smith
Reference (section label): [basic.life]/1.5
Link to reflector thread (if any):
Issue description:
[basic.life]/1.5 says:
The lifetime of an object o of type T ends when [...] the storage which the object occupies [...] is reused [...]
but what does that mean? In llvm/llvm-project#61562 we have two possible interpretations:
- In an expression
new (p) T(x)
, the lifetime of*p
ends whenp
is returned fromvoid* operator new(size_t, void*)
, beforex
is evaluated. - In an expression
new (p) T(x)
, the lifetime of*p
ends the moment the constructor body starts executing, afterx
is evaluated.
Note that interpretation (2) only works when the initialization is performed by a constructor or if T
is a non-class type, and we must use interpretation (1) for aggregate initialization because the evaluation of x
can directly initialize a part of the resulting object.
Suggested resolution:
To me, it seems that the most consistent and simplest model is that the lifetime of *p
ends the moment that p
is returned from an operator new
function invoked by a new-expression, and in particular, the object no longer exists in the evaluation of the new-initializer.
Alternatively, we could say that the the lifetime ends as late as possible -- the moment anything actually starts initializing the new object (perhaps, when a constructor starts running or a value is stored for the object or any of its subobjects). That's probably going to be challenging for constant interpreters to model, though.