静态存储持续时间初始化
Static-storage-duration initialization
C++静态存储持续时间对象以未指定的顺序初始化(同一编译单元除外)。
使用如下代码:
#include <iostream>
struct Foo {
Foo() {
std::cout << "Hello, world.n";
}
} foo_instance;
int main(int argc, const char *argv[]) {
return 0;
}
在标准中哪里说我已经可以在foo_instance
初始化期间使用std::cout
?
我知道我可以通过在<iostream>
中添加一些技巧来确保事情会起作用,例如让它包含类似的东西
int __ensure_stdout_initialization_call();
namespace {
int __ensure_stdout_initialization
= __ensure_stdout_initialization_call();
}
然而,问题是在哪里保证对标准库所需的所有初始化都这样做。
tl;博士;在初始化foo_instance
期间不应使用std::cout
。
无论标准中标准流初始化如何,唯一的要求是
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 初始化之前排序。
因此,ios_base::Init
将在变量和标准流准备就绪之前初始化,但是如果您在包含变量之前声明变量,似乎仍然可以<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;
}
死亡示例
所以我可以得出结论,在非局部变量的动态初始化过程中,你不能使用 std::cout。
我不确定它是否在标准 (*) 中明确说明,但通常 std::cin、std::cout 和 std::cerr是在 Nifty Counter 习语的帮助下实现的。
基本思想是在头文件中包含一个帮助程序静态对象,在初始化期间,检查流对象是否已初始化,如果没有,则对其进行初始化。通常包括首先出现,此类帮助程序静态对象在同一转换单元中的任何其他静态对象之前初始化,并确保在任何其他静态对象引用流对象之前正确初始化它。
(*)编辑:
以下是标准草案N3936的适当措辞:
27.4 标准 iostream 对象
27.4.1.2
构建对象并在 类对象之前或期间的某个时间 ios_base::Init 是构造的,并且在任何情况下在主体之前 开始执行。在程序期间不会销毁对象 执行。在翻译单元中包含
的结果 应好像定义了 ios_base::Init 的实例 静态存储持续时间。同样,整个程序的行为应为 如果至少有一个 ios_base::Init 的静态实例 存储持续时间。
看看标题<iostream>
。
该标准说它的行为就像它定义了一个类型为std::ios_base::Init
的TU本地对象,它处理初始化并在最后刷新标准流。
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 静态存储持续时间初始化
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 均衡符号和初始化之间的时间和空间复杂性是否存在差异
- 我应该如何在主函数中初始化时间
- C++中结构的存储持续时间和成员初始化
- 模板实例化对编译持续时间的影响
- 初始化结构向量需要大量的编译时间
- 以合理的编译时间静态初始化巨大的uint8_t数组
- 变量初始化的时间有关系吗
- 对于静态初始化的大数组(例如65536条目),编译时间非常长
- 是块作用域静态或线程存储持续时间变量初始化失败的原因
- c++中静态数据初始化的时间和方式
- 数组初始化的时间复杂度是多少?
- 初始化带有静态存储时间的std::数组,带有参数Pack扩展和附加值
- 声明一个结构并立即用cv限定符或存储持续时间说明符对其进行实例化
- 是静态存储持续时间初始化为NULL或全零的对象中未初始化的指针
- 在main()之前初始化对象的静态存储持续时间