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

Reid Kleckner via cfe-dev cfe-dev at lists.llvm.org
Tue Jul 19 07:11:30 PDT 2016


I also don't like subsetting the language even more (-fno-exceptions,
-fno-rtti, -fno-sized-allocation, etc), but this is another one of those
C++ features that really isn't "pay for what you use".

The simplest way to avoid paying for static destruction is to turn it off
completely.

On Mon, Jul 18, 2016 at 5: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.
>
> _______________________________________________
> 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/20160719/bdce0c5d/attachment.html>


More information about the cfe-dev mailing list