C++ – Is it true that calling _exit() instead of exit() won’t prevent static destructors from being called

clinux

On comp.lang.c++.moderated@googlegroups.com, Greg Herlihy posted the following extern "C" function:

extern "C" 
{
    int func()
    {
        wchar_t memoryName[256];
        wchar_t mutexName[256];
        wchar_t eventName[256];
        mbstowcs(memoryName, "MemoryName", 256);
        mbstowcs(mutexName, "MutexName", 256);
        mbstowcs(eventName, "EventName", 256);
        std::wstring memoryString(memoryName);
        std::wstring mutexString(mutexName);
        std::wstring eventString(eventName);
        CDataTransferServer *srv = new CDataTransferServer();
        srv->Initialize(1, CC_SAMPLETYPE_MPEG4,128,256,64);
        printf("Inside entry point tester 1\n");
        srv->AddUser(5, memoryString, mutexString, eventString);
        printf("Inside entry point tester 2\n");
        delete srv;
        printf("Exiting entry point tester 3\n");                                                      
    }
} 

which is a g++ entry point different than main(int argc, char*argv[]).

Greg Herlihy then wrote:

Calling _exit() (which presumably should be "_Exit()") – does not "prevent"
C++ global objects from being destroyed. The destruction of a C++ program's
global objects is not inevitable. Instead a C++ program is responsible for
destroying its own global objects – and can do so in one of two ways: the
program returns from main() or it calls exit(). So a C++ program that fails
to exit main() and neglects to call exit() before it terminates – will not
have destroyed its global objects by the time it ended.

I don't believe that follows from what is written in the standard.

As far as I can see, when I call exit(), the spec guarantees that:

  • Destructors for objects with automatic storage duration
    will not be called.

  • Destructors for objects with with static storage duration
    will be called, in reverse order of construction.

The worrying thing is that the standard doesn't say anything about
exit() or _exit(), so I'm relying on implementation-dependent behavior.

Not so. The C++ Standard specifies that calling exit() destroys global
objects[3.6.3/1] And _Exit() is part of the C99 Standard (and will
presumably be incorporated into the next C++ Standard by reference).

Right, the C++ standard says what exit() does, but it doesn't say what
_exit() or _Exit() do. And the C standard certainly doesn't say
anything about C++ destructors.

I don't see any implementation-defined behavior here. Calling _Exit() is no
more likely to destroy a C++ program's global objects than calling printf()
– or calling any other function that is not exit().

_exit() and _Exit() are specified not to call any functions registered
atexit() or on_exit(). However, that's not useful for C++ because the
C++ spec doesn't say by what means the runtime takes care of calling
destructors of objects with static storage duration. A compliant
implementation could use a mechanism other than atexit() or on_exit()
to invoke static destructors.

In other words, the C++ spec does not say anything all about the
behavior of _exit() or _Exit(). Therefore, I cannot make any assumptions
about whether or not calling either function will cause destructors
of static objects to run or not.

Any comments are welcome.

Best Answer

Right, the C++ standard says what exit() does, but it doesn't say what _exit() or _Exit() do.

From n3290 which, if I'm not mistaken, is the C++11 standard excepted minor last minute editorial changes:

The function _Exit(int status) has additional behavior in this International Standard:

  • The program is terminated without executing destructors for objects of automatic, thread, or static storage duration and without calling functions passed to atexit()

There is no description of _exit (but then the C standard does not describe _exit either).

Related Topic