https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed|2006-02-05 21:10:26 |2022-11-2 --- Comment #12 from Jonathan Wakely <redi at gcc dot gnu.org> --- Reduced from the code in libstdc++: extern "C" int puts(const char*); struct A { constexpr A() { } ~A() { puts("bye"); } }; namespace { struct constant_init { union { A obj; }; constexpr constant_init() : obj() { } ~constant_init() { /* do nothing, union member is not destroyed */ } }; // Single-threaded fallback buffer. constinit constant_init global; } extern "C" A* get() { return &global.obj; } With -std=c++20 -Os GCC emits a call to atexit: (anonymous namespace)::constant_init::~constant_init() [base object destructor]: ret get: mov eax, OFFSET FLAT:_ZN12_GLOBAL__N_16globalE ret _GLOBAL__sub_I_get: mov edx, OFFSET FLAT:__dso_handle mov esi, OFFSET FLAT:_ZN12_GLOBAL__N_16globalE mov edi, OFFSET FLAT:_ZN12_GLOBAL__N_113constant_initD1Ev jmp __cxa_atexit With the same options, Clang doesn't: get: # @get lea rax, [rip + (anonymous namespace)::global] ret