[cfe-dev] -Wglobal-constructors warns on constexpr default constructor evaluated at compile-time?

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Tue Jan 16 15:28:24 PST 2018


On 16 January 2018 at 12:12, Friedman, Eli via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On 1/16/2018 11:26 AM, Gabriel Charette wrote:
>
>
>
> On Tue, Jan 16, 2018 at 8:00 PM Richard Smith <richard at metafoo.co.uk>
> wrote:
>
>> On 16 January 2018 at 10:43, Friedman, Eli via cfe-dev <
>> cfe-dev at lists.llvm.org> wrote:
>>
>>> On 1/16/2018 4:14 AM, Gabriel Charette via cfe-dev wrote:
>>>
>>>> I would indeed expect, like Primiano, that -Wglobal-constructors would
>>>> only warn about *con*structors (one can decide to mitigate global
>>>> *de*structors another way, e.g. by invoking _exit() before end of main()).
>>>>
>>> The point of -Wglobal-constructors is to avoid code which runs at
>>> process startup.  Due to the way the C++ ABI works, a global destructor
>>> involves emitting a call to __cxa_atexit which runs at startup, so we warn.
>>>
>>
>> Well, there are (at least) four distinct problems here:
>>
>>  1) Code running at process startup (a performance problem)
>>  2) Code running at process termination (a performance problem)
>>  3) Global variables with non-constant initialization resulting in buggy
>> program startup (called the "initialization order fiasco" by some)
>>  4) Global variables with non-trivial destruction resulting in buggy
>> program shutdown, particularly in multithreaded code (if you have
>> non-trivial global dtors, multiple threads, and you call exit, you
>> typically have a bug)
>>
>> It makes sense to request warnings about #3 without requesting the more
>> general warnings about #1; as such, ignoring destructors in the
>> -Wglobal-constructors warning would seem reasonable to me. (That allows all
>> four problems to be detected by some combination of the two warning flags.)
>>
>
> Yes, precisely.
>
> A program can decide to mitigate against 2/4 by atomically exiting with
> _exit() before the end of main() and hence truly only want to be warned by
> 1/3.
>
> I'm not sure (3) is a problem this warning solves well; there are a lot of
> classes with constructors which aren't constexpr, but don't have relevant
> side-effects (for example, std::vector).
>
Yes, but it depends on how you try to solve (3). If you allow
dynamically-initialized globals, but only if they don't reference other
dynamically-initialized globals, you're right that this is pretty far from
ideal. But that approach is fraught with peril, since even
innocuous-seeming changes become wrong if you happen to be changing code
that's reachable from a dynamically-initialized global. A more reliable
(but obviously more restrictlve) approach is to avoid
dynamically-initialized globals altogether, which this warning does help
with :) Given the ongoing expansion of the powers of constexpr evaluation,
the more restrictive approach is likely to become appropriate for more
projects over time.

> But I guess we could introduce a new warning flag.  (We probably don't
> want to change the meaning of the current warning flag for the sake of
> compatibility with existing build systems.)
>
> On a side-note, it would be nice if the following worked to suppress
> global destructors:
>
> struct A { ~A(); };
> template<typename T> union NoDestroy {
>   T t;
>   constexpr NoDestroy():t{} {}
>   constexpr ~NoDestroy() {}
> };
> NoDestroy<A> x;
>
This already suppresses the global dtor when compiled with optimization
enabled (and the 'constexpr' on the destructor removed): we optimize out
__cxa_atexit calls registering empty functions, IIRC. Support for constexpr
destructors is working its way through the C++ committee right now, and
that should behave as you expect on the above example (removing the global
dtor).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180116/16ad9086/attachment.html>


More information about the cfe-dev mailing list