rjmccall added a comment.

In D61165#1487100 <https://reviews.llvm.org/D61165#1487100>, @erik.pilkington 
wrote:

> It seems like the most common sense interpretation here is to just treat the 
> initialization of `G` as completed at the point when the constructor finishes 
> (this appears to be what GCC implements: 
> https://wandbox.org/permlink/R3C9pPhoT4efAdL1).


Your example doesn't actually demonstrate that that's what GCC implements 
because it doesn't try to execute the declaration twice.  But you're right, GCC 
does appear to consider the initialization complete as soon as the static 
object's constructor returns normally.  On the other hand, GCC gets the array 
case here wrong: if a static local has array type, and a destructor for a 
temporary required by the first element initializer throws, then it does not 
destroy the element but also (correctly) does not mark the variable as fully 
initialized, and so a second attempt to run the initializer will simply 
construct a new object on top of an already-constructed one.  This is arguably 
correct under the standard — the first array element is not a 
previously-constructed object of automatic duration — but I hope it's obvious 
that that's a defect.

> So if it was static it would just get destroyed at exit-time, and therefore 
> should be disable-able with `no_destroy`. If the standard implies that we 
> should be doing something else, then we should do that, but I can't seem to 
> find any reference to the rule you're describing.

Like I said, this is a poorly-specified part of the standard, because at least 
*some* objects with static storage duration have to be destroyed when an 
exception is thrown (because of aggregate initialization), but the standard 
wants to pretend that this isn't true.  I think that allowing temporary 
destructors to cancel initialization uniformly across all kinds of objects is 
the most consistent rule, but if the standard wants to use a rule that 
non-aggregate initialization of static and thread-local locals is complete as 
soon as the constructor (or assignment) completes, as opposed to the end of the 
full-expression, that's also implementable.  I guess it would also technically 
be feasible for repeated attempts at initialization to just pick up after the 
last subobject to be successfully constructed, although that would be really 
obnoxious to actually implement (and would require an ABI change for static 
local aggregates with vague linkage).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61165/new/

https://reviews.llvm.org/D61165



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to