成员初始化的循环依赖

时间:2016-05-05 11:35:09

标签: c++ initialization

我正在尝试以下C ++代码,它基于不同命名空间中的静态变量c1c2来初始化成员变量v1v2。在我看来,这些变量的初始化会发生循环依赖。

#include <iostream>

namespace M1
{
    struct T1
    {
        int c1;
        T1();
    };

    T1 v1;
}

namespace M2
{
    struct T2
    {
        int c2;
        T2() { c2 = M1::v1.c1; }            // (1)
        // T2() : c2( M1::v1.c1 ) {}        // (2)
    };

    T2 v2;
}

M1::T1::T1() { c1 = M2::v2.c2; }            // (3)
// M1::T1::T1() : c1( M2::v2.c2 ) {}        // (4)


int main()
{
    std::cout << M1::v1.c1 << std::endl;
    std::cout << M2::v2.c2 << std::endl;

    return 0;
}

但是,如果我使用g ++ - 5.3(在OSX 10.9上通过自制软件安装)编译此代码,它总是成功符合(-Wall没有警告)并给出

0
0

我也尝试用(2)和(4)代替行(1)和(3),但结果没有变化(即00)。所以我想知道为什么这段代码成功运作。这里没有循环依赖?如果没有,结果是否未定义? (即内存中的c1和c2打印的垃圾数据?)我将不胜感激任何有关此行为的提示。谢谢!

1 个答案:

答案 0 :(得分:2)

是的,由于值是相互初始化的,因此您具有循环依赖关系。

没有任何错误,原因几乎与以下原因相同:

int x;
std::cout << x;

在那里,逻辑上,你只是简单地使用未初始化的变量。该值将是未指定的,并且编译器在一般情况下无法检测到这一点,因此在任何情况下都不会。

但是,我们还必须记得静态存储持续时间的对象在几乎任何其他事情发生之前都是零初始化的,因此您的程序实际上是定义良好的。

这意味着M2::v2.c2肯定会被初始化为零;因此,M1::v1.c1也将初始化为零。