Global Initialization Order in C : Ignoring Dependencies
In C , the initialization order of global variables within a translation unit is well-defined. However, dependencies between globals can be ignored, leading to surprising behavior.
Consider the following code:
<code class="cpp">struct Foo; extern Foo globalFoo; struct Foo { Foo() { printf("Foo::Foo()\n"); } void add() { printf("Foo::add()\n"); } static int addToGlobal() { printf("Foo::addToGlobal() START\n"); globalFoo.add(); printf("Foo::addToGlobal() END\n"); return 0; } }; Foo globalFoo; int dummy = Foo::addToGlobal(); int main() { printf("main()\n"); return 0; }</code>
When compiled with GCC 4.4.3, the expected output is:
Foo::Foo() Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END main()
This is because the global variable globalFoo is initialized before calling the static method Foo::addToGlobal(). However, if we swap the order of globalFoo and dummy declaration, the output becomes:
Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END Foo::Foo() main()
It appears that the instance methods of Foo are being called on an unconstructed instance. This is because the order of global initialization ignores dependencies.
To ensure the constructor of Foo is called before initializing dummy, we need to make sure globalFoo is defined before dummy in the same translation unit. Alternatively, we can use a static pointer to the global instance, which will be initialized to null before any dynamic initialization. The addToGlobal method can then check if the pointer is null and create the global Foo if necessary.
The above is the detailed content of Why Does Swapping Global Variable Declarations in C Lead to Unexpected Behavior?. For more information, please follow other related articles on the PHP Chinese website!