静态存储持续时间初始化 [英] Static-storage-duration initialization

查看:43
本文介绍了静态存储持续时间初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中,静态存储持续时间对象以未指定的顺序初始化(在同一编译单元中除外).

In C++ static-storage-duration objects are initialized in unspecified order (except in the same compilation unit).

使用如下代码:

#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 吗?

where is stated in the standard I can already use std::cout during initialization of foo_instance?

我知道我可以通过在< iostream> 中添加一些技巧来确保一切正常,例如,使其中包含类似

I know I can ensure things will work by adding some trickery in <iostream>, for example by having it containing something like

int __ensure_stdout_initialization_call();
namespace {
    int __ensure_stdout_initialization
      = __ensure_stdout_initialization_call();
}

但是问题是,对于标准库所需的所有初始化,在哪里可以保证做到这一点.

the question is however about where it's guaranteed that this is done for all initialization needed by the standard library.

推荐答案

tl; dr;在初始化 foo_instance 的过程中,请勿使用 std :: cout .

tl;dr; You should not use std::cout during initialization of foo_instance.

与标准中标准流的初始化无关的唯一要求是

The only requirement regardless initialization of standard streams in standards is

27.4.1概述[iostream.objects.overview]

27.4.1 Overview [iostream.objects.overview]

3构造对象并在第一次构造类 ios_base :: Init 的对象之前或期间的某个时间建立关联,无论如何在main主体之前开始执行.291在程序执行过程中,对象没有被破坏.292将< iostream> 包含在翻译单元中的结果应该好像< iostream> 定义了 ios_base :: Init 的实例一样具有静态存储期限.

3 The objects are constructed and the associations are established at some time prior to or during the first time an object of class ios_base::Init is constructed, and in any case before the body of main begins execution. 291 The objects are not destroyed during program execution. 292 The results of including <iostream> in a translation unit shall be as if <iostream> defined an instance of ios_base::Init with static storage duration.

因此,如果在声明静态变量之前包含< iostream> ,则可以保存,因为符合标准

So if you include <iostream> before declaring your static variable you are save because according to standard

3.6.3动态初始化非局部变量[basic.start.dynamic]

3.6.3 Dynamic initialization of non-local variables [basic.start.dynamic]

2具有静态存储持续时间的非局部变量V和W的动态初始化的顺序如下:(2.1)如果V和W已排序初始化,并且V在单个转换单元中的W之前定义,则V的初始化在W的初始化之前进行排序.

2 Dynamic initialization of non-local variables V and W with static storage duration are ordered as follows: (2.1) If V and W have ordered initialization and V is defined before W within a single translation unit, the initialization of V is sequenced before the initialization of W.

因此 ios_base :: Init 将在变量和标准流准备就绪之前初始化,但是似乎如果在<包括< iostream> :

so ios_base::Init will be initialized before your variable and standard streams will be ready, but it seems that you can still shot yourself in the leg if you declare your variable before including <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.

So I can conclude that you can not use std::cout during dynamic initialization of non-local variables.

这篇关于静态存储持续时间初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆