Global Initialization Order and Dependency Resolution in C
In C , global variables within a single translation unit are initialized in the order they are defined. However, there is no well-defined order for global variables across different translation units. This ambiguity can lead to unexpected behavior, as illustrated in the following code:
<code class="cpp">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();</code>
When addToGlobal is called before globalFoo is initialized, the behavior is as expected:
Foo::Foo() Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END main()
However, when the order is reversed, the constructor for Foo is not called, and globalFoo is somehow accessible within addToGlobal:
Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END Foo::Foo() main()
This behavior is attributed to the fact that the order of initialization for globals ignores any dependencies between them. In this case, dummy depends on globalFoo, but their initialization order is not guaranteed.
To ensure that the constructor for Foo is called before using globalFoo, one solution is to create a static pointer to the global instance and test whether it is null within addToGlobal. If it is null, the global Foo is created before any dynamic initialization.
The above is the detailed content of Why Can Global Variables in Different Translation Units Lead to Unexpected Behavior in C ?. For more information, please follow other related articles on the PHP Chinese website!