1

All old and modern C++ books and experts state to initialize class members by their declaration order. But neither explains what if I don't?? I am not talking about classes with members of const types or smth.. just plain simple class.

Consider the sample:

class A
{
  int n;
  std::vector<double> VD;
  char c;
public:
  A():
      VD(std::vector<double>(3)),
      c('a'),
      n(44)
      {
      }
};

Whats the difference of written code and the one with same order in which they are declared???

Eduard Rostomyan
  • 7,050
  • 2
  • 37
  • 76
  • 1
    I don't know about the books, but at least [cppreference.com](http://en.cppreference.com/w/cpp/language/initializer_list#Initialization_order) tells you: >The order of member initializers in the list is *irrelevant*: the actual order of initialization is as follows: ... – Olaf Dietsche Feb 22 '18 at 14:24

6 Answers6

7

Whats the difference of written code and the one with same order in which they are declared???

If members don't depend on each other's initialization order, there is no difference whatsoever. But if they do, then a member initialization list may be telling a lie.

Many a programmer were bitten by this, when they thought their constructors were written correctly, but in fact they had undefined behavior on their hands.

Consider this simple case:

struct foo {
  int _a;
  int _b;
  foo(int b) : _b(b), _a(2 * _b) {}
};

What's _a in the above example? If you answer anything but "the behavior is undefined because _b is used initialized", you'd be wrong.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
6

But neither explains what if I don't?

Programmers have no control over it: the order in which you list members in the initialization list has no effect on the actual order of initialization. The compiler ignores the order of items on the list, and re-orders the expressions to match declaration order.

Here is a short example to illustrate this point:

struct Foo {
    Foo(const char *s) { cout << "Init " << s << endl; }
};
struct Bar {
    Foo a;
    Foo b;
    Foo c;
    Bar() : c("c"), b("b"), a("a") {
    }
};

The above prints

Init a
Init b
Init c

even though initialization lists the items in opposite order.

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
4

There ought to be absolutely no difference in the generated assembly, although the "as-if" rule might get in the way.

Conceptually at least, n is initialised before c.

Reference: http://en.cppreference.com/w/cpp/language/as_if

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
3

You can't change initialisation order - it's the order the members appear in the class - the order in the initialisation list is not significant, though compilers may warn if the two orders don't match up.

0

I think there are two reasons to order them properly.

  1. The same order as they are declared makes the code more readable, especially when you want to add or remove some more variables.
  2. The order they are declared indicates their order in the memory. You have more locality when you initialize the variables.
Kozuki
  • 97
  • 8
0

It depends on how the members are used. If there is a dependency then order must be followed.

Consider below example.

    class x{
         size_t n;
         char * ch; // the size of dynamic char array depends on n
     }

Here, initializing in different order will result in undefined behavior

Other than this reason, of course readability and uniformity matters from coding guidelines POV.

Sitesh
  • 1,816
  • 1
  • 18
  • 25