在 C++ 中,静态存储持续时间对象以未指定的顺序初始化(同一编译单元中的除外)。
代码如下:
#include <iostream>
struct Foo {
Foo() {
std::cout << "Hello, world.\n";
}
} foo_instance;
int main(int argc, const char *argv[]) {
return 0;
}
标准中规定的位置我已经可以使用std::cout
在初始化期间foo_instance
?
我知道我可以通过添加一些技巧来确保事情顺利进行<iostream>
,例如让它包含类似的东西
int __ensure_stdout_initialization_call();
namespace {
int __ensure_stdout_initialization
= __ensure_stdout_initialization_call();
}
然而,问题在于如何保证标准库所需的所有初始化都完成此操作。
太长;博士;你不应该使用std::cout
在初始化期间foo_instance
.
无论标准中标准流的初始化,唯一的要求是
27.4.1 概述 [iostream.objects.overview]
3 在第一次创建类对象之前或期间的某个时间构造对象并建立关联ios_base::Init
被构造,并且无论如何在 main 主体开始执行之前。 291 程序执行期间对象不会被破坏。第292章 包括的结果<iostream>
在翻译单元中应如同<iostream>
定义了一个实例ios_base::Init
具有静态存储时间。
所以如果你包括<iostream>
在声明静态变量之前,您将被保存,因为根据标准
3.6.3 非局部变量的动态初始化[basic.start.dynamic]
2 具有静态存储持续时间的非局部变量 V 和 W 的动态初始化顺序如下:
(2.1) 如果 V 和 W 已排序初始化,并且在单个翻译单元内 V 定义在 W 之前,则 V 的初始化将排序在 W 的初始化之前。
so ios_base::Init
将在你的变量和标准流准备好之前初始化,但如果你声明你的变量,你似乎仍然可以射中自己的腿before包括<iostream>
:
struct Foo
{
Foo();
} foo_instance; // uses ::std::cout
#include <iostream> // declares ios_base::Init variable that will init ::std::cout
Foo::Foo()
{
std::cout << "Hello, world.\n";
}
int main(int argc, const char *argv[]) {
return 0;
}
垂死的例子 http://ideone.com/7dJG1J
所以我可以得出结论,在非局部变量的动态初始化期间不能使用 std::cout 。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)