C 中的全局初始化顺序和依赖解析
在 C 中,单个翻译单元内的全局变量按照定义的顺序进行初始化。然而,不同翻译单元之间的全局变量没有明确定义的顺序。这种歧义可能会导致意外的行为,如以下代码所示:
<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>
当在初始化 globalFoo 之前调用 addToGlobal 时,行为符合预期:
Foo::Foo() Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END main()
但是,当顺序颠倒时,不会调用 Foo 的构造函数,并且可以在 addToGlobal 中以某种方式访问 globalFoo:
Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END Foo::Foo() main()
此行为归因于以下事实:全局变量的初始化顺序忽略了它们之间的任何依赖关系。在这种情况下,dummy 依赖于 globalFoo,但不能保证它们的初始化顺序。
为了确保在使用 globalFoo 之前调用 Foo 的构造函数,一种解决方案是创建一个指向全局实例的静态指针并进行测试addToGlobal 中是否为 null。如果为 null,则在任何动态初始化之前创建全局 Foo。
以上是为什么不同翻译单元中的全局变量会导致 C 中的意外行为?的详细内容。更多信息请关注PHP中文网其他相关文章!