In the GCC docs I found the -fuse-cxa-atexit
option and it says the following:
This option is required for fully standards-compliant handling of static destructors
So what is the difference between the two? In the docs for __cxa_atexit
I found the following:
The __cxa_atexit() function is used to implement atexit()
I'm implementing statics in functions (don't ask why) and I was wondering which of the 2 to use for calling the destructor.
And I guess I only have atexit()
for MSVC? Is that a problem?
Can I just use atexit()
everywhere and be sure that it would behave just like real static objects in functions would?
__cxa_atexit()
is defined in the Itanium C++ ABI. The document explained the motivation behind this function:
The C++ Standard requires that destructors be called for global objects when a program exits in the opposite order of construction. Most implementations have handled this by calling the C library
atexit
routine to register the destructors. This is problematic because the 1999 C Standard only requires that the implementation support 32 registered functions, although most implementations support many more. More important, it does not deal at all with the ability in most implementations to remove [Dynamic Shared Objects] from a running program image by callingdlclose
prior to program termination.The API specified below is intended to provide standard-conforming treatment during normal program exit, which includes executing
atexit
-registered functions in the correct sequence relative to constructor-registered destructors, and reasonable treatment during early DSO unload (e.g.dlclose
).
So:
__cxa_atexit()
is not limited to 32 functions.__cxa_atexit()
will call the destructor of the static of a dynamic library when this dynamic library is unloaded before the program exits.You should enable -fuse-cxa-atexit
if you are writing a library, and your libc has this function (e.g. glibc, musl). In fact, the gcc that comes with your distro might have this flag enabled automatically already (there will be a linker error if you enable the flag and the libc doesn't support it).
Note that users should not call __cxa_atexit
directly: it takes arguments which only the compiler/linker is supposed to know (the __dso_handle
).
… No user interface to
__cxa_atexit
is supported, so the user is not able to register anatexit
function with a parameter or a home DSO.
MSVC apparently does not use atexit()
-like functions to run the global destructors. And according to Destructor of a global static variable in a shared library is not called on dlclose MSVC already run destructors on dlclose()
.