https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to R. Diez from comment #5) > First of all, GCC seems unable to generate an empty routine or destructor, > or at least flag it as being effectively empty. The caller should then > realise that it is empty, so it is not worth generating an atexit call for > it. The object has a user-provided destructor, which is necessary for the immortalization trick to work. Being user-provided means it's non-trivial and that means the destructor must be run. To destroy a gobal object, atexit it used. Now if the compiler can tell that the destructor actually has no side effects, it's unobservable whether the atexit call ever happens. But that takes non-trivial analysis of the destructor body and hard-coded knowledge that atexit has no *other* observable side effects except registering the destructor This all requires special case handling in the compiler, not just "turn on -Os and all the code gets removed".