Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

According to the standard, is std::vector affected by the static initialization order problems?

Can I safely store things in a vector in constructors of non-pod static data member constructors? Example:

class Foo
{
public:
    static Foo& instance()
    {
        static Foo inst;
        return inst;
    }

    void store(int x) { numbers.push_back(x); }

private:
    Foo() {}
    std::vector<int> numbers;
};

class Bar
{
public: 
    Bar() { Foo::instance().store(5); }
};

class Thing
{
public:
    static Bar bar;
};

// in thing.cpp:
Bar Thing::bar;

Is the above code correct and produces defined behavior?

Note: The question is not about static locals, but about std::vector depending on any static initialization that might not happen until the bar constructor.

like image 479
Tamás Szelei Avatar asked Dec 19 '22 17:12

Tamás Szelei


2 Answers

Static variables inside a function or method are initialized on the first call. Thus the above snippet will work as intended.

Call Order:

  1. Bar constructor
  2. Foo::instance()
  3. Foo constructor (static variable initialization)
like image 179
Sebastian Hoffmann Avatar answered Feb 16 '23 02:02

Sebastian Hoffmann


std::vector does not use any static data, so it is safe.

Even a strange implementation that did use static data in std::vector would be required to ensure that its use of that data was safe and invisible to you (e.g. by using local statics instead of global objects), so you can assume it behaves as if it doesn't use any static data.

Inserting into a std::vector does use the freestore (aka heap) which is global and uses static data, but that is safe to do from global constructors and is not specific to std::vector but applies to any memory allocation done by global constructors before main starts.

like image 25
Jonathan Wakely Avatar answered Feb 16 '23 01:02

Jonathan Wakely