hookenz
hookenz

Reputation: 38987

What is the order of evaluation in a member initializer list?

I have a constructor that takes some arguments. I had assumed that they were initialized in the order listed, but in one case, it appears they were being initialized in reverse, resulting in an abort. When I reversed the arguments, the program stopped aborting.

Below is an example of the syntax I'm using. a_ needs to be initialized before b_ in this case. Can you ensure this order of initialization?

class A
{
  public:
    OtherClass a_;
    AnotherClass b_;

    A(OtherClass o, string x, int y)
      : a_(o)
      , b_(a_, x, y) {}
};

Upvotes: 303

Views: 92769

Answers (4)

GManNickG
GManNickG

Reputation: 504323

For clarification, the standard, under class.base.init, states:

In a non-delegating constructor, initialization proceeds in the following order:

...

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

Upvotes: 226

SolomidHero
SolomidHero

Reputation: 178

Seeing other answers without to much details into other members initialization I recommend reading more info from standard reference 12.6.2 section 13 (thanks @Adam Getchell for link):

In a non-delegating constructor, initialization proceeds in the following order:

(13.1) — First, and only for the constructor of the most derived class (1.8),
virtual base classes are 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 classes in the derived class base-specifier-list.

(13.2) — Then, direct base classes are initialized in declaration order
as they appear in the base-specifier-list
(regardless of the order of the mem-initializers).

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

(13.4) — Finally, the compound-statement of the constructor body is executed.

Terminology:

base-specifier-list - list of base classes for derived class. See section 10 of reference.
Example: class A : public virtual B, private C

mem-initializers - list of initializers for members of your class.
Example: A::A() : number(1.0f), text("abc"){ /* ... */}

compound-statement - block of {}, i.e. body of constructor.


That's all, simply said the order:

  1. static variables (see this stackoverflow question C++ static variables initialization order, also that interesting behavior SIOF). In single translation unit order follows declaration order, in different - compilers decide.
  2. virtual base classes as appear by dfs
  3. direct base classes as specified by order in deriving list
  4. non-static variables by declaration (! not initializers order) order

Upvotes: 0

Khaled Alshaya
Khaled Alshaya

Reputation: 96929

It depends on the order of data member declarations in the class. So a_ will be the first one, then b_ will be the second one in your example.

Upvotes: 345

Adam Getchell
Adam Getchell

Reputation: 455

The standard reference for this now appears to be 12.6.2 section 13.3:

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

Upvotes: 32

Related Questions