Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializer list *argument* evaluation order

So, the C++ standard requires that class members be initialized in the order in which they are declared in the class, rather than the order that they're mentioned in any constructor's initializer list. However, this doesn't imply anything about the order in which the arguments to those initializations are evaluated. I'm working with a system that frequently passes references to serialization objects around, and wondering if I can ensure that bits are read from it in the right order, independent of the order in which those bits get written into the object's fields.

struct Foo {
    int a;
    double b;
    // I want to be able to do this
    Foo(SerObj &s)
    : b(s.readDouble()), a(s.readInt())
    { }
    // Rather than this
    Foo (SerObj &s)
    {
        b = s.readDouble();
        a = s.readInt();
    }
};

Obviously, reordering things like ints and doubles in the declaration is not too big a deal, but bigger objects and things requiring dynamic allocation sometimes can be.

like image 639
Phil Miller Avatar asked Oct 19 '09 17:10

Phil Miller


People also ask

What is the order of initialization for data?

In the initializer list, the order of execution takes place according to the order of declaration of member variables. While using the initializer list for a class in C++, the order of declaration of member variables affects the output of the program. Program 1: C++

Does order of initializer list matter?

The order of the initializer list does NOT matter. The declaration of your members in the class header defines the initialization order. This is by design and required as you could have multiple ctors having totally different init list orders.

Is initializer list faster?

Conclusion: All other things being equal, your code will run faster if you use initialization lists rather than assignment.

Is assigned in constructor body consider performing initialization in initialization list?

Note: It is mandatory that a reference or a const member must be intialized in a constructor initialization list. They cannot be 'assigned' in the body of the constructor.


1 Answers

C++ Standard 12.6.2/3:

There is a sequence point (1.9) after the initialization of each base and member. The expression-list of a mem-initializer is evaluated as part of the initialization of the corresponding base or member.

The order of the initialization is the one you specified in the question. Evaluation is part of this initialization, and the initializations can't interleave (because there is a sequence point between them).

That means that the function calls in your initializer lists are not called in the desired order, but in the order in which the member declarations appear.

like image 122
Johannes Schaub - litb Avatar answered Sep 18 '22 05:09

Johannes Schaub - litb