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

Ben Craig via llvm-dev llvm-dev at lists.llvm.org
Tue Jul 17 10:52:50 PDT 2018


My interpretation of the C++ standard is that today's freestanding C++ implementations (between C++98 and C++17) are already allowed to skip global destructors.  http://eel.is/c++draft/basic.start#main-1

So re-label the toolchain from hosted to freestanding, change nothing else except start-up and termination, and you still have a compliant (but unorthodox) implementation.

I've got a paper that discusses some of this (along with a lot of other embedded-hostile features) here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1105r0.html


> -----Original Message-----
> From: cfe-dev <cfe-dev-bounces at lists.llvm.org> On Behalf Of David Chisnall
> via cfe-dev
> Sent: Tuesday, July 17, 2018 2:15 AM
> To: JF Bastien <jfbastien at apple.com>
> Cc: cfe-dev at lists.llvm.org; Bruno Cardoso Lopes <blopes at apple.com>
> Subject: Re: [cfe-dev] [RFC] Suppress C++ static destructor registration
> 
> On 16 Jul 2018, at 22:55, JF Bastien via cfe-dev <cfe-dev at lists.llvm.org>
> wrote:
> >
> > Concrete example
> >
> > Greg Parker provided this example of thread-related issues in the previous
> discussion:
> >
> > The Objective-C runtime has a global table that stores retain counts. Pretty
> much all Objective-C code in the process uses this table. With global
> destructors in place this table is destroyed during exit(). If any other thread is
> still running Objective-C code then it will crash.
> >
> > Currently the Objective-C runtime avoids the destructor by initializing this
> table using placement new into an aligned static char buffer.
> >
> > I’m assuming that the embedded usecase is obvious enough to everyone
> to not need an example. Let me know if that’s not the case.
> 
> I have hit this issue a few times with similar solutions (either placement new,
> or simply new and leak the pointer), so I agree that this is a problem that
> needs solving.  That said, I rarely want to disable *all* static destructors,
> instead I want to either disable some or define ordering between them
> (which I can do by disabling some and explicitly calling them from another).
> 
> I would much prefer to see a [[no_destroy]] attribute or similar, to disable
> registering destructors for a specific static / global, than a different language
> mode.  I would also see a simplification of some code with a
> [[lazy_construct]] attribute so that I could declare a global and have it follow
> the same initialisation rules as a static, rather than having to create a static
> and a function that returns a reference to it.
> 
> I would; however, point out that exit() is not the only time that static
> destructors are run.  The C++ standard pretends that shared libraries don’t
> exist (and added thread-local variables with nontrivial destructors in such a
> way that gives implementers two possible bad choices if they have to
> support library unloading), but in the real world they do.  It’s difficult to see
> how such a mode would coexist with a world that supports loading and
> unloading of shared libraries.  Perhaps a sanitiser could check that the objects
> have been destroyed when the library is unloaded?
> 
> David
> 
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi-
> 2Dbin_mailman_listinfo_cfe-
> 2Ddev&d=DwIGaQ&c=I_0YwoKy7z5LMTVdyO6YCiE2uzI1jjZZuIPelcSjixA&r=y8
> mub81SfUi-UCZRX0Vl1g&m=HxCl5f-t-
> UkQZp2CkeD_xRdlXcwFkEmw0QbDAVUlQ64&s=M4RhJONiFXWSmezJsv1xLQ
> oNt--UJoWYQ2vVyn7s730&e=


More information about the llvm-dev mailing list