rafeeq
rafeeq

Reputation: 11

Static variable definition order in c++

Hi i have a class tools which has static variable std::vector m_tools.

Can i insert the values into the static variable from Global scope of other classes defined in other files.

Example:

tools.h File

class Tools
{
public:
static std::vector<std::vector> m_tools;

void print()
{
for(int i=0 i< m_tools.size() ; i++)
std::cout<<"Tools initialized :"<< m_tools[i];
}
}

tools.cpp File

std::vector<std::vector> Tools::m_tools;  //Definition

Using register class constructor for inserting the new string into static variable.

class Register
{
public:
  Register(std::string str)
{
Tools::m_tools.pushback(str);
}

};

Different class which inserts the string to static variable in static variable

first_tool.cpp

//Global scope declare global register variable


Register a("first_tool");



////////

second_tool.cpp

//Global scope declare global register variable


Register a("second_tool");

Main.cpp

void main()
{
Tools abc;
abc.print();
}

Will this work?

In the above example on only one string is getting inserted in to the static list. Problem look like "in Global scope it tries to insert the element before the definition is done" Please let me know is there any way to set the static definiton priority? Or is there any alternative way of doing the same.

Upvotes: 1

Views: 956

Answers (3)

P&#233;ter T&#246;r&#246;k
P&#233;ter T&#246;r&#246;k

Reputation: 116266

The initialization order of static global variables in different compilation units is not defined in C++ - this is why you have a problem.

A workaround may be to call a static function which contains the first static variable as local. This way you can force it to be initialized before it is used:

// tools.h

class Tools
{
public:
  static std::vector<std::vector>& getTools();
  ...
};

// tools.cpp

std::vector<std::vector>& Tools::getTools() {
  static std::vector<std::vector> tools;
  return tools;
}

...
class Register
{
public:
  Register(std::string str)
  {
    Tools::getTools().pushback(str);
  }
};

Upvotes: 1

neuro
neuro

Reputation: 15180

The initialization of statics is not specified by C++. C++ FAQ Lite call it the "static initialization order fiasco"

my2c

Upvotes: 0

Matthieu M.
Matthieu M.

Reputation: 299810

You are likely, here, to encounter the issue referred to as Initialization Order Fiasco.

The problem is that the initialization order of globals (and static class variables are globals) is well-defined within a same translation unit (roughly, think .cpp) but is completely undefined across translation units. Therefore, there is no guarantee that the vector be initialized when you try to push items in there.

Your solution here ? Use local static variables:

class Tools
{
public:
  static std::vector<std::string>& AccessTools()
  {
    static std::vector<std::string> Tools; // local static
    return Tools;
  }
private:
};

class Register
{
public:
  Register(std::string str)
  {
    Tools::AccessTools().push_back(str);
  }

};

It is guaranteed to be initialized upon first access... though it's not (and cannot be) thread safe; if you are in a multithreading situation, you need to call Tools::AccessTools in main before launching the other threads to guarantee the initialization.

Upvotes: 3

Related Questions