tags:

views:

152

answers:

5

Oh C++ gurus, I seek thy wisdom. Speak standardese to me and tell my if C++ guarantees that the following program:

#include <iostream>
using namespace std;

struct A
{
    A() { cout << "A::A" << endl; }
    ~A() { cout << "A::~" << endl; }
};

struct B
{
    B() { cout << "B::B" << endl; }
    ~B() { cout << "B::~" << endl; }
};

struct C
{
    C() { cout << "C::C" << endl; }
    ~C() { cout << "C::~" << endl; }
};

struct Aggregate
{
    A a;
    B b;
    C c;
};

int main()
{
    Aggregate a;
    return 0;
}

will always produce

A::A
B::B
C::C
C::~
B::~
A::~

In other words, are members guaranteed to be initialized by order of declaration and destroyed in reverse order?

+1  A: 

Members will be initialized in order, yes; destroyed in reverse? dunno.

+2  A: 

Yes and yes. The order of destruction is always opposite to the order of construction, for member variables.

Chris Jester-Young
+9  A: 

Yes, they are (non-static members that is). See 12.6.2/5 for initialization (construction) and 12.4/6 for destruction.

AndreyT
+1 for noting that this is for _non-static_ members. :-)
Chris Jester-Young
+9  A: 

In other words, are members guaranteed to be initialized by order of declaration and destroyed in reverse order?

Yes to both. See 12.6.2

6 Initialization shall proceed in the following order:

  • First, and only for the constructor of the most derived class as described below, virtual base classes shall be initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base class names in the derived class base-specifier-list.

  • Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).

  • Then, non-static data members shall be initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

  • Finally, the compound-statement of the constructor body is executed. [ Note: the declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. —end note ]

dirkgently
If I remember correctly, yes to both...Think of it as a stack. First pushed, last poped. So, when instantiating your first instance, it is pushed into memory in order of a stack. Then, the second is pushed over, the third over the second and so forth. Then, when destroying your instances, the program shall look for the first to destroy, the last that has been pushed.But I might be wrong explaning it this way, but it is the way I learned it when doing C/C++ and ASM.
Will Marcouiller
+1  A: 

Yes, the standard guarantees objects get destructed in the reverse order they were created. The reason is that one object may use another, thus depend on it. Consider:

struct A { };

struct B {
 A &a;
 B(A& a) : a(a) { }
};

int main() {
    A a;
    B b(a);
}

If a were to destruct before b then b would hold an invalid member reference. By destructing the objects in the reverse order in which they were created we guarantee correct destruction.

wilhelmtell