Home > Software engineering >  What should happen if one calls `std::exit` in a global object's destructor?
What should happen if one calls `std::exit` in a global object's destructor?

Time:10-27

Consider the following code:

#include <cstdlib>
struct Foo {
    ~Foo() {
        std::exit(0);
    }
} foo;
int main() {
}

It compiles and terminates with zero successfully for me both on my Linux (GCC, Clang) and Windows (Visual Studio). However, when compiled with MSYS2's GCC on Windows (g (Rev2, Built by MSYS2 project) 10.3.0), it enters an infinite recursion and dies from stack overflow. This can be checked by adding some debug output right before std::exit(); I did not add it initially to avoid thinking about the destruction of std::cout.

Does any C standard have anything to say about such behavior? Is it well-defined/implementation-defined/undefined/etc and why?

For instance, [support.start.term]/9.1 of some recent draft says the following about std::exit's behavior:

First, objects with thread storage duration and associated with the current thread are destroyed. Next, objects with static storage duration are destroyed and functions registered by calling atexit are called. See [basic.start.term] for the order of destructions and calls.

which refers to [basic.start.term]/1, I guess:

Constructed objects ([dcl.init]) with static storage duration are destroyed and functions registered with std​::​atexit are called as part of a call to std​::​exit ([support.start.term]). The call to std​::​exit is sequenced before the destructions and the registered functions.

I don't see any immediate restriction on calling std::exit in a destructor.

Sidenote: please refrain from commenting that "this code is bad", "thou shalt not use destructors in global objects" (which you probably should not) and probing for the XY problem in the comments. Consider this an academic question from a curious student who knows a much better solution to their original problem, but have stumbled upon this quirk while exploring the vast meadows of C .

CodePudding user response:

[basic.start.main]/4:

If std​::​exit is called to end a program during the destruction of an object with static or thread storage duration, the program has undefined behavior.

  • Related