Given a static member variable that is initialized from a member static variable of another class, the non-literal struct ii sometimes initialized by default to 0 or to 333 . It depends on the compilation or binding order. Pseudo code to demonstrate:
class StaticClass: // file 'ONE.cpp/.hpp' static int i = 2 static struct ii { int a = 333 } class ABC: // file 'abc.cpp' static int abc_i = StaticClass::i // always 2 static struct abc_ii = StaticClass::ii // sometimes 0, sometimes 333
Calling g++ -std=c++11 abc.cpp ONE.cpp && ./a.out results in i = 2 / ii = 0 (gcc 4.8.1, same thing with clang ++ 3.7; -Wall -Wextra never complains )
But calling g++ -std=c++11 ONE.cpp abc.cpp && ./a.out leads to i = 2 / ii = 333 !
The same thing happens with ONE.o abc.o vs abc.o ONE.o , as well as when concatenating files one way or another:
cat ONE.cpp abc.cpp > X.cpp && g++ X.cpp && ./a.out vs cat abc.cpp ONE.cpp > Y.cpp && g++ Y.cpp && ./a.out
Deletion turns on and moves the code in one file; when this order is launched, the initialization is 0 by default:
const OneI ABC::def_ii = StaticClass::ii; const OneI StaticClass::ii = OneI{333};
and from one to 333 with this order:
const OneI StaticClass::ii = OneI{333}; const OneI ABC::def_ii = StaticClass::ii;
Why does this happen even with two separate compilation units? Can this be somehow avoided by forcing the latter to order all the time? Is using a static pointer in ABC before StaticClass::ii safe (I would rather not do this)?
Full C ++ code:
#include <iostream> #include "ONE.hpp" struct ABC { ABC(); static const int def_i; static const OneI def_ii; void arg_i(const int &x) { std::cout << "i = " << x << " ";}; void arg_ii(const OneI &x) { std::cout << "/ ii = " << xa << " ";}; }; ABC::ABC() { arg_i(def_i); arg_ii(def_ii); } const int ABC::def_i = StaticClass::i; const OneI ABC::def_ii = StaticClass::ii; int main() { ABC a; std::cout << '\n'; } /* End: abc.cpp */
#include <iostream> #include "ONE.hpp" const int StaticClass::i = 2; const OneI StaticClass::ii = OneI{333}; /* End: ONE.cpp */
#include <iostream> #ifndef One #define One struct OneI { OneI(int a_) : a(a_) { } int a; }; struct StaticClass { const static int i; const static OneI ii; }; #endif // One header guard /* End: ONE.hpp */
c ++ static c ++ 11
toting
source share