std::不能保证初始化吗? < >我知道C++是不应该假定全局实例的构造(和破坏)的顺序。< /P>

std::不能保证初始化吗? < >我知道C++是不应该假定全局实例的构造(和破坏)的顺序。< /P>,c++,constructor,global-variables,C++,Constructor,Global Variables,当我使用构造函数和析构函数中使用std::cout的全局实例编写代码时,我遇到了一个问题 std::cout也是iostream的一个全局实例。std::cout是否保证在任何其他全局实例之前初始化 我写了一个简单的测试代码,它工作得很好,但我仍然不知道为什么 #include <iostream> struct test { test() { std::cout << "test::ctor" << std::endl; } ~test()

当我使用构造函数和析构函数中使用
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;
}

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

根据§27.3/2

对象[std::cin、std::cout等]被构造,并且 协会是在第一次会议之前或会议期间建立的 构造ios_base::Init类的对象时,以及在任何情况下 在主体开始执行之前


你的问题是关于静态对象的构造顺序。我相信语言规范没有定义它

GCC有一个属性来处理订单


我相信你在实践中不必担心那么多。

答案因使用的是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(){std::cout,它没有说明相对于其他静态对象的
std::cout
的构造顺序。@basilestrynkevitch:有点正确,但脚注265(参考§27.3/2)说它应该起作用:静态对象的构造函数和析构函数可以访问这些对象,以从stdin读取输入,或将输出写入stdout或stderr。这可能不是规范性的,但至少清楚地说明了他的代码应该工作的意图。@BasileStrynkevich:事实上是这样。本段继续:包含在翻译单元中的结果应被定义为具有静态存储持续时间的ios_base::Init实例。”并且由于同一翻译单元中的静态非局部变量按照声明的顺序初始化,
cout
保证在其他非局部静态变量之前已初始化。(假设您在声明变量之前包含
,我衷心希望)@克纳顿:如果在声明静态变量的
之前包含其他标题呢?@MatthieuM。我同意,但这也不是我的观点。标准确实没有指定何时初始化
cout
。它只指定对于特定的翻译单元,结果就像在该标题中定义了一个实例一样。这只是一种标准方法,可以确保即使在静态对象中也可以安全地使用
cout
。与此相关的还有答案中的构造。不能假设全局范围内静态存储持续时间对象的初始化顺序,但有一些技巧可以强制初始化顺序。PS。还要注意de的顺序构造是有保证的(与构造相反)。在C++03中,明显的意图(如脚注所示)是保证std::cin/std::cout对象在其他对象之前被完全构造。
#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;
}