Hi Guys, There appears to be a discrepancy in the way that G++ orders its static destructors. Given this test program:
#include <iostream> using namespace std; class A { public: int i; A(int j) : i(j) { cout << "constructor A" << endl; } ~A() { cout << "destructor A : i = " << i << endl; } }; class B { public: A *n; B() { static A p(1); n = &p; cout << "constructor B" << endl; } ~B() { cout << "destructor B : i = " << n->i << endl; n->i = 10; } }; class B x1; int main (void) { return 0; } When compiled and run using an x86_64 native gcc built from today's sources this program will produce this output: constructor A constructor B destructor A : i = 1 destructor B : i = 1 However when compiled using a 3.4.4 native x86_64 compiler the following is produced when the program is run: constructor A constructor B destructor B : i = 1 destructor A : i = 10 Looking at what I hope is the right part of the C++ language specification: 3.6.3 - Termination [basic.start.term] -1- Destructors (class.dtor) for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from main and as a result of calling exit (lib.support.start.term). These objects are destroyed in the reverse order of the completion of their constructor or of the completion of their dynamic initialization. If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized. For an object of array or class type, all subobjects of that object are destroyed before any local object with static storage duration initialized during the construction of the subobjects is destroyed. This appears to state that the 3.4.4 compiler got it right. The problem I believe is that the destructor for class A is registered to run using atexit() when the constructor for class B is run, but the destructor for class B is permanently recorded in the .dtors section. Since the exit() function runs the things recorded with atexit() first, before calling _exit() which runs the destructors in the .dtors section, the destructor for A is called before the destructor for B. Can anyone clarify this for me ? Is this a bug with the current G++ implementation ? Cheers Nick