首页  >  文章  >  后端开发  >  如何保证C中具有依赖关系的全局变量的正确初始化?

如何保证C中具有依赖关系的全局变量的正确初始化?

Linda Hamilton
Linda Hamilton原创
2024-11-03 22:56:02693浏览

 How to Guarantee Proper Initialization of Global Variables in C   with Dependencies?

C 全局初始化顺序:探索依赖关系

在 C 中,翻译单元中的全局变量通常按照声明的顺序进行初始化。但是,在考虑跨多个翻译单元的初始化顺序时,可能会出现混乱。

初始问题场景

考虑以下代码:

<code class="cpp">struct Foo {
    Foo() { printf("Foo::Foo()\n"); }
    void add() { printf("Foo::add()\n"); }
    static int addToGlobal() {
        globalFoo.add();
        return 0;
    }
};

Foo globalFoo;

int dummy = Foo::addToGlobal();

int main() { printf("main()\n"); return 0; }</code>

与这段代码,预期的输出是:

Foo::Foo()
Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
main()

但是,交换 dummy 和 globalFoo 的声明和初始化会产生不同的输出:

Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
Foo::Foo()
main()

初始化顺序和依赖关系

此行为表明全局变量的初始化顺序忽略了依赖关系。在这种情况下,对 Foo::addToGlobal() 的调用尝试在调用其构造函数之前访问 Foo 的方法。

解决方案:确保正确的初始化

为了确保 Foo 的构造函数在 dummy 初始化之前被调用,我们可以在同一翻译单元中在 dummy 之前定义 globalFoo。这保证了 globalFoo 将首先被初始化,从而允许 addToGlobal() 成功访问其方法。

替代解决方案:静态初始化守卫

或者,我们可以引入静态Foo::addToGlobal() 内的初始化保护:

<code class="cpp">static Foo* pFoo = nullptr;

if (pFoo == nullptr) {
    pFoo = &globalFoo;
}

pFoo->add();</code>

此检查确保指针 pFoo 在访问其方法之前已初始化为 globalFoo,有效防止过早使用 globalFoo。

以上是如何保证C中具有依赖关系的全局变量的正确初始化?的详细内容。更多信息请关注PHP中文网其他相关文章!

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