是否保证std :: cout被初始化?

时间:2012-01-09 07:00:00

标签: c++ constructor global-variables

我对C ++的了解是不应该假设全局实例的构造(和析构)的顺序。

我正在使用构造函数&中使用std::cout的全局实例编写代码。析构函数,我有一个问题。

std::cout也是iostream的全局实例。是否保证std::cout在任何其他全局实例之前被初始化?

我写了一个简单的测试代码,它运行得很好,但我仍然不知道为什么。

#include <iostream>

struct test
{
    test() { std::cout << "test::ctor" << std::endl; }
    ~test() { std::cout << "test::dtor" << std::endl; }
};

test t;

int main()
{
    std::cout << "Hello world" << std::endl;
    return 0;
}

打印

test::ctor
Hello world
test::dtor

代码是否有可能无法按预期运行?

3 个答案:

答案 0 :(得分:40)

答案取决于您使用的是C ++ 03还是C ++ 11。

在C ++ 11中,您的代码保证可以正常工作,但在C ++ 03中,它是未指定的;您唯一的保证是,在输入main()时,标准流已初始化。 (也就是说,所有主流实现在运行任何动态初始化之前都会对它们进行初始化,这样可以很好地使用它们。)

您可以通过构建std::ios_base::Init对象强制进行初始化,如下所示:

#include <iostream>

struct test
{
    test() { std::cout << "test::ctor" << std::endl; }
    ~test() { std::cout << "test::dtor" << std::endl; }

private:
    std::ios_base::Init mInitializer;
};

test t;

int main()
{
    std::cout << "Hello world" << std::endl;
    return 0;
}

现在test构建时,它会初始化mInitializer并保证流可以使用。

C ++ 11修复了这种有点恼人的行为,就好像#include <iostream>的每个实例都跟着static std::ios_base::Init __unspecified_name__;一样。这样可以自动保证流可以使用。

答案 1 :(得分:10)

根据§27.3/ 2

  

构造对象[std :: cin,std :: cout等],并且   在第一次之前或期间的某个时间建立关联   时间构建ios_base :: Init类的对象,无论如何   在主体开始执行之前。

答案 2 :(得分:2)

您的问题是关于静态对象的构造顺序。我相信语言规范是不确定的。

GCC具有init_priority属性来玩订单。

我相信你在实践中不应该太担心。