4

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.

Tamás Szelei
  • 23,169
  • 18
  • 105
  • 180
  • related: http://stackoverflow.com/questions/8102125/is-local-static-variable-initialization-thread-safe-in-c11 – Nate Kohl Mar 05 '14 at 20:32
  • `Thing::bar` might be affected by global initialization order; but not the local variable `inst`. – dyp Mar 05 '14 at 20:33

2 Answers2

6

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)
Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77
  • The question is not about static locals, but about std::vector depending on any static initialization that might not happen until the bar constructor. – Tamás Szelei Mar 05 '14 at 20:42
5

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.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • Is it explicitly stated in the standard that std::vector either does not depend or only "transparently" depends on static initialization? – Tamás Szelei Mar 05 '14 at 20:57
  • I don't see how a std::vector object would be different from a user defined object. In this case, the static function constructs the object so the object and its non-static vector must have been created before the call to store. I can't prove a negative though. I wouldn't know where to look within the standard in order to answer the question that you've asked. I don't believe that there are any problems in the example that you posted. The thing to be worry about is static objects depending on other static objects. In this case static functions don't do anything unless they are called. – shawn1874 Mar 05 '14 at 21:23
  • @TamásSzelei, it's not explicitly stated, but I would argue it doesn't need to be. No types in the standard library have the problem you are worried about. It is not a problem. – Jonathan Wakely Mar 05 '14 at 23:18