简体   繁体   English

是否可以确保std :: cout初始化?

[英]Is std::cout guaranteed to be initialized?

What I know about C++ is that the order of the constructions (and destructions) of global instances should not be assumed. 我对C ++的了解是,不应假定全局实例的构造(和销毁)顺序。

While I'm writing code with a global instance which uses std::cout in the constructor & destructor, I got a question. 当我使用在构造函数和析构函数中使用std::cout的全局实例编写代码时,我遇到了一个问题。

std::cout is also a global instance of iostream. std::cout也是iostream的全局实例。 Is std::cout guaranteed to be initialized before any other global instances? 是否可以确保在其他全局实例之前初始化std::cout

I wrote a simple test code and it works perfectly, but still I don't know why. 我编写了一个简单的测试代码,它可以完美运行,但是我仍然不知道为什么。

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

It prints 它打印

test::ctor
Hello world
test::dtor

Is there any possibility that the code doesn't run as expected? 代码是否有可能无法按预期运行?

The answer differs depending on if you're using C++03 or C++11. 根据您使用的是C ++ 03还是C ++ 11,答案会有所不同。

In C++11, your code is guaranteed to work, but in C++03 it's unspecified; 在C ++ 11中,保证您的代码可以工作,但是在C ++ 03中,未指定代码; your only guarantee is that by the time main() is entered, the standard streams had been initialized. 您唯一的保证是,在输入main() ,已经初始化了标准流。 (That said, all mainstream implementations initialize them prior to running any dynamic initialization, making them fine to use.) (也就是说,所有主流实现在运行任何动态初始化之前都会对其进行初始化,以使其易于使用。)

You can force initialization by constructing an std::ios_base::Init object, like so: 您可以通过构造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;
}

Now when test constructs, it initializes mInitializer and guarantees the streams are ready to use. 现在,当test构造时,它将初始化mInitializer并确保流准备就绪。

C++11 fixed this slightly annoying behavior by acting as if every instance of #include <iostream> were followed by static std::ios_base::Init __unspecified_name__; C ++ 11通过充当#include <iostream>每个实例后跟static std::ios_base::Init __unspecified_name__;解决此烦人的行为static std::ios_base::Init __unspecified_name__; . This automatically guarantees the streams are ready to use. 这将自动保证可以使用流。

According to §27.3/2 : 根据§27.3/ 2

The objects [std::cin, std::cout, etc.] are constructed, and the associations are established at some time prior to or during first time an object of class ios_base::Init is constructed, and in any case before the body of main begins execution. 构造对象[std :: cin,std :: cout等],并在构造ios_base :: Init类的对象之前或第一次期间的某个时间以及在任何情况下,在建立之前建立关联。主要主体开始执行。

Your question is about the order of construction of static objects. 您的问题与静态对象的构造顺序有关。 I believe that the language specification leaves it undefined. 我相信语言规范会使其保持未定义状态。

GCC has the init_priority attribute to play with the order. GCC具有init_priority属性以处理订单。

And I believe you should not worry that much in practice. 我相信您在实践中不必担心那么多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM