|<<>>|268 of 275 Show listMobile Mode

C++ Initializer List Ordering

Published by marco on

Updated by marco on

The April issue of the C++ Users Journa[1] published a letter by Ashley Williams pointing out yet another wart of C++. For any class in C++, you may declare as many member variables as you like. Each one of these member variables may be initialized in the constructor in the “initializer list”. References, in fact, must be initialized in this list.

Now, if you had to guess, in which order would those initializers be called? In the order they’re written? Remember that parameters passed to a function have no guaranteed ordering or execution. The compiler may order the execution of passed parameters as it sees fit. Perhaps you’re thinking that initializers are subject to the same logic (or lack thereof) and have no set execution order. You’d be wrong. In fact, the C++ standard does enforce an ordering on execution of initializers. Do you think that that ordering is the order in which you’ve written them? Of course not, that would be too simple, straightforward and easy-to-use and hence, not very C++.

class A
{
  public:
    A ();

  private:
    B        aB;
    BManager aBM;
};

A::A () : aBM (), aB (aBM) {}

In the example above, member aB is initialized using member aBM. However, according to the C++ standard (Section 10.4.6, emphasis added):

“The members’ constructors are called before the body of the containing class’ own constructor is executed. The constructors are called in the order in which the members are declared in the class rather than the order in which the members appear in the initializer list.”

So, aBM is not initialized when aB tries to use it. Now, of course, it makes sense to initialize member variables in the order that they’re declared, but does anyone else get the feeling that this language is working against you? Can you imagine how many errors lurk in source code because of this exact assumption? It makes you wonder whether the guys that made up InterCal had a hand in C++.


[1] This used to link to http://www.cuj.com. That site has, since publication, been taken over by an unrelated entity. h/t to Joanna Palmer, who took the time to let me know.