[cfe-dev] [RFC] Suppress C++ static destructor registration

Sean Silva via cfe-dev cfe-dev at lists.llvm.org
Mon Jul 18 15:03:18 PDT 2016


On Mon, Jul 18, 2016 at 2:08 PM, Richard Smith via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On Mon, Jul 18, 2016 at 1:39 PM, Bruno Cardoso Lopes via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
>> Hi,
>>
>> C++ static destructors can be problematic in multi-threaded
>> environment. Some of the issues users often complain about include:
>> 1. Teardown ordering: crashes when one thread is exiting the process
>> and calling destructors while another thread is still running and
>> accessing the destructing variables
>> 2. Shared code that is compiled both as an application and as a
>> library. When library mode is chosen, goto (1).
>> 3. Some projects currently override __cxa_atexit to avoid the behavior
>> in question.
>>
>> To get around that, I propose we add a compiler option (e.g.
>> -fno-cxx-static-destructors) to allow clang to suppress destructor
>> registration (currently done via __cxa_atexit, atexit):
>> https://reviews.llvm.org/D22474
>>
>> I'm opening this discussion here on cfe-dev to get some feedback on the
>> matter
>>
>> One can argue that dealing with C++ static destructors in
>> multi-threaded environment is solely the responsibility of the
>> developer, however since (AFAIK) we don't have any standard guaranteed
>> semantic for "global destruction vs. threads", it seems fair to me
>> that we could give developers some option.
>
>
> They already have options. They can use std::quick_exit, which was added
> specifically to address this problem, if they don't want destructors to be
> run at all. There are standard techniques to avoid destructors being run
> for specific objects:
>
>   template<typename T> union not_destroyed {
>     T value;
>     template<typename ...U> constexpr not_destroyed(U &&...u) :
> value(std::forward<U>(u)...) {}
>     ~not_destroyed() {}
>   };
>   not_destroyed<std::string> my_str("foo"); // technically has object
> lifetime issues
>
>   ... or ...
>
>   std::string &&s = *new std::string("foo");
>
> Are these options not good enough? Is per-TU control (with no source
> changes) a goal here, or is it more of an incidental property of the
> solution? It seems to me that we should prefer to either push people
> towards the standard std::quick_exit solution or propose an alternative
> standard mechanism rather than invent our own proprietary way to work
> around this problem.
>


This doesn't sound like Bruno's use case, but at least for games, we know
they never exit (or when they do they don't care about destructors).
Avoiding emitting destructors can give a size benefit in such scenarios.
Also, it can theoretically (I have not measured this, but it doesn't sound
far-fetched) eliminate some references to global variables which in an LTO
context can allow for more aggressive optimizations.

-- Sean Silva


>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160718/6de6abed/attachment.html>


More information about the cfe-dev mailing list