首页 >后端开发 >C++ >为什么不同翻译单元中的全局变量会导致 C 中的意外行为?

为什么不同翻译单元中的全局变量会导致 C 中的意外行为?

Barbara Streisand
Barbara Streisand原创
2024-10-30 02:51:281032浏览

 Why Can Global Variables in Different Translation Units Lead to Unexpected Behavior in C  ?

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn