1

Consider the following example:

// header props.h

#pragma once
#include <vector>
extern std::vector<int> prop;
struct addToVec
{
    addToVec(int a)
    {
        prop.push_back(a);
    }
};

// cpp file props.cpp

#include "props.h"
std::vector<int> prop;
addToVec b(10);

// main.cpp

#include <iostream>
#include "props.h"
addToVec a2(14);
int main(int argc, char** argv)
{
    std::cout << prop.size();
    return 0;
}

The expected out is 2. But the actual output is 1.

This gives the expected result (2) on gcc compiler (not sure of the version). I am using visual studio professional 2013 version 12 update 5. Is this a bug or an expected result?

The order in which the elements are added to the vector doesn't concern me. My only concern is that only one element is added to the vector(instead of 2).

Jarod42
  • 203,559
  • 14
  • 181
  • 302
PVRT
  • 480
  • 4
  • 13
  • The order in which the elements are added to the vector doesn't concern me. My only concern is that only one element is added to the vector(instead of 2). – PVRT Jan 24 '18 at 10:00
  • 1
    The order that does matter is whether `prop` is created before or after the instances of `addToVec`. – quamrana Jan 24 '18 at 10:04

3 Answers3

4

While the order of initialization is well-defined within a single translation unit, it is not defined between translation units.

This means you have no control of if prop will be constructed and initialized before or after a2.

One more reason to avoid global variables.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

To counter Static Initialisation Ordering you could use a function with a static member:

// header props.h

#pragma once
#include <vector>
std::vector<int>& getProp();
struct addToVec
{
    addToVec(int a)
    {
        getProp().push_back(a);
    }
};

// cpp file props.cpp

#include "props.h"
std::vector<int>& getProp(){
    static std::vector<int> prop;
    return prop;
}
addToVec b(10);

In this way, prop is only created when it is needed.

quamrana
  • 37,849
  • 12
  • 53
  • 71
1

This is an instance of the "Static Initialization Order Fiasco" - see e.g. static initialization order fiasco.

The initialization order of non-local objects is not defined in C++ so in cases like this you cannot rely on the initialization order of prop versus a2. You'll have to pick one (or both) to be explicitly initialized under your control instead of relying on the undefined order.

Joris Timmermans
  • 10,814
  • 2
  • 49
  • 75