C ++全局初始化顺序忽略依赖性? [英] C++ global initialization order ignores dependencies?

查看:82
本文介绍了C ++全局初始化顺序忽略依赖性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为我的问题最好在代码中描述:

I think my problem is best described in code:

#include <stdio.h>

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;
}

上面的打印(用gcc 4.4.3):

The above prints (with gcc 4.4.3):

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

但是,当我交换以下行时:

However, when I swap the following lines:

Foo globalFoo;
int dummy = Foo::addToGlobal();

int dummy = Foo::addToGlobal();
Foo globalFoo;

程序输出以下内容:

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

看起来 Foo 正在使用尚未构建的实例进行调用!在全局范围内移动变量的声明就像影响程序的行为一样简单,这导致我相信(1)未定义全局变量的初始化顺序和(2)全局变量的初始化顺序忽略所有依赖关系。它是否正确?是否可以确保在初始化 dummy ?之前调用 Foo 的构造函数?

It seems instance methods of Foo are being called using an instance which has not yet been constructed! Something as simple as moving the declaration of a variable in the global scope is affecting the behaviour of the program, and that leads me to believe (1) the order of initialization of globals is not defined and (2) the order of initialization of globals ignores all dependencies. Is this correct? Is it possible to make sure the constructor of Foo is called before initializing dummy?

我试图解决的问题是静态地填充项目(静态实例 Foo )的存储库。在我目前的尝试,我使用一个宏(其中)创建一个全局变量(在一个匿名命名空间,以避免名称冲突),其初始化触发静态初始化。也许我从错误的角度来解决我的问题?有更好的替代品吗?感谢。

The problem I am trying to solve is filling a repository of items (a static instance of Foo) statically. In my current attempt, I am using a macro which (among other things) creates a global variable (in an anonymous namespace to avoid name clashing) whose initialization triggers the static initialization. Perhaps I'm tackling my problem from the wrong angle? Is there a better alternative(s)? Thanks.

推荐答案

在初始化的顺序,请阅读答案此处

On the order of initialization, read the answer here.

有关如何解决初始化问题,可以将全局变量作为函数中的静态局部变量。有标准保证静态局部变量将在第一次调用函数时初始化:

On how to solve the initialization issue, you can push the global to be a static local variable in a function. There standard guarantees that the static local variable will be initialized in the first call to the function:

class Foo {
public:
   static Foo& singleton() {
      static Foo instance;
      return instance;
   }
};

然后,您的其他全局变量将访问该变量:

Then your other global variables would access the variable as:

Foo::singleton().add();

注意,这通常不被认为是一个好的设计,而且即使这解决了初始化问题,它不解决定案的顺序,所以你应该小心,不要访问单体后,它已被销毁。

Note that this is not generally considered as a good design, and also that even if this solves the initialization issues, it does not solve the order of finalization, so you should be careful not to access the singleton after it has been destroyed.

这篇关于C ++全局初始化顺序忽略依赖性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆