Almost verbatim from the standard:
/// 1. Objects with static storage duration are destroyed
///    and functions registered by calling atexit are
///    called. Objects with static storage duration are
///    destroyed in the reverse order of the completion
///    of their constructor.
/// 2. Functions registered with atexit are called in the
///    reverse order of their registration. A function
///    registered with atexit before an object obj1 of static
///    storage duration is initialized will not be called until
///    obj1’s destruction has completed. A function registered
///    with atexit after an object obj2 of static storage
///    duration is initialized will be called before obj2 
///    destruction starts.

#include <iostream>

static void pre_exit(void) {
        std::cout << "@pre_exit" << std::endl;
}
static void post_exit(void) {
        std::cout << "@post_exit" << std::endl;
}

struct FIRST {
        FIRST() {
                atexit(pre_exit);
                std::cout << "FIRST::FIRST()" << std::endl;
        }
        ~FIRST() {
                std::cout << "FIRST::~FIRST()" << std::endl;
        }
};
struct SECOND {
        SECOND()  { std::cout << "SECOND::SECOND()" << std::endl; }
        ~SECOND() { std::cout << "SECOND::~SECOND()" << std::endl; }
};

static FIRST    _first;
static SECOND   _second;

///////////////
int main() {
        if (atexit(post_exit)) { /* registration failed */ }
        std::cout << "whatever" << std::endl;
        std::cout.flush();
        return 0;
}

///// the output is:
FIRST::FIRST()
SECOND::SECOND()
whatever
@post_exit
@pre_exit
SECOND::~SECOND()
FIRST::~FIRST()

/// where I would expect it to be:
FIRST::FIRST()
SECOND::SECOND()
whatever
@post_exit
SECOND::~SECOND()
@pre_exit
FIRST::~FIRST()

/// or maybe even
FIRST::FIRST()
SECOND::SECOND()
whatever
@post_exit
SECOND::~SECOND()
FIRST::~FIRST() // pre_exit was registered before FIRST() completed.
@pre_exit


-- 
           Summary: invocation order of functions registered with atexit()
                    not as expected
           Product: gcc
           Version: 3.3.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ivan at sierra-da dot com
 GCC build triplet: linux/i686/rh9
  GCC host triplet: linux/i686/rh9
GCC target triplet: linux/i686/rh9


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26723

Reply via email to