1
Vector::Vector(const Vector& a) : elem{new double[sz]}, sz{a.sz}
{
  for(int i = 0; i!= sz; ++i)
      elem[i] = a.elem[i];
}

The interesting part here is that elem{new double[sz]} comes before

sz{a.sz}

so that is, before

sz

is initialized.

But it doesn't throw any error, right?

Can someone tell me something about the corresponding part in the standard, a deeper insight in the inner workings, or how in any other way this is regulated?

Starhowl
  • 434
  • 5
  • 14
  • 4
    Well it's Undefined Behavior if `sz` wasn't initialized, but that doesn't mean a crash will happen. It also depends on the order of the member declaration in the class. If `sz` is declared before `elem` it will be initialized first in the initializer list, thus avoiding UB. – David G May 26 '14 at 18:03

1 Answers1

10

The important thing about initialization list is that members are not initialized in order of their appearance in initialization list but in order of declaration in class.

C++ Standard n3337 § 12.6.2/10 Initializing bases and members

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

— 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.

— 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).

— 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).

— 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 ]

( now I will repeat my other answer but I think this won't hurt anyone) This is important. Remember this to avoid errors like

/* trying to allocate (possibly) very large block of memory
   as a result of initializing a vector with
   uninitialized integer: std::vector<int> v( N)
*/
class SearchEngine {
    std::vector<int> v;
    int N;
    explicit SearchEngine( std::vector<int> const& keys)
                  : N( keys.size()), v( N), {
4pie0
  • 29,204
  • 9
  • 82
  • 118