Search code examples
c++global-variablesstatic-variables

How to initialize a static variable with another static variable?


Static1.hpp

#include <string>
class Static1
{
    public:
        static const std::string my_string;
};

Static1.cpp

#include "Static1.hpp"
const std::string Static1::my_string = "aaa";

Static2.hpp

#include <string>
class Static2
{
    public:
        static const std::string my_string;
};

Static2.cpp

#include "Static2.hpp"
const std::string Static2::my_string = Static1::my_string;

main.cpp

#include "Static2.hpp"
#include <iostream>

int main(argc int, char** argv)
{
     cout << to_string(Static2::my_string == "aaa") << endl;
     return 0;
}

If I put add_executable(printMyString main.cpp Static2.cpp Static1.cpp) in my CMakeLists.txt, I get

0

while add_executable(printMyString main.cpp Static2.cpp Static1.cpp) gives me the expected behavior of

1

To make my code easier to maintain (so that I don't need to keep track of the order I list my source files), is there any way I can ensure that I get the behavior where Static2::my_string == "aaa"?


Solution

  • You are experiencing effects of a static initialization order fiasco.

    The usual work-around is to substitute your static variables with functions that have a static variable in the scope, initialize, and return it.


    Here is how it could be done for your example: Live Example (order1) Live Example (order2)

    class Static1
    {
        public:
            static std::string my_string();
    };
    

    ...

    std::string Static1::my_string()
    {
       static const std::string my_string = "aaa";
       return my_string;
    }
    

    ...

    class Static2
    {
        public:
            static std::string my_string();
    };
    

    ...

    std::string Static2::my_string()
    {
       static const std::string my_string = Static1::my_string();
       return my_string;
    }
    

    ...

    std::cout << std::to_string(Static2::my_string() == "aaa") << std::endl;