静态订单初始化失败,iostream和C ++ 11

男性主义者

根据C ++ 11规范:

包含<iostream>在翻译单元中的结果应如同<iostream>定义了ios_base::Init具有静态存储持续时间的实例同样,整个程序的行为应类似于至少一个ios_base::Init具有静态存储持续时间的实例

这意味着如果我的代码如下所示:

// A.cpp
#include <iostream>
using namespace std;
unsigned long foo() {
    cerr << "bar"; 
    return 42;
}

// B.cpp

using namespace std;
extern unsigned long foo();

namespace {
unsigned long test() {
    int id = foo();
    return id;
}

unsigned long id = test();
}


int main() {
     return 0;
}

那么我应该可以安全地进行呼叫,cerr而不会出现静态初始化失败的风险。

不幸的是,该代码存在段错误...为什么?我不认为gcc 6.2.1决定忽略C ++ 11规范,而是将其包含<iostream>在A.cpp中。根据规范,它就足够了。

博·佩尔森

该段的全引号包括:

在构造ios_base :: Init类的对象之前或第一次期间的某个时间,以及无论如何在main主体开始执行之前的某个时间,都将构造对象并建立关联。293)

还有脚注

293)如果他们有可能这样做,则鼓励实现比所需的早初始化对象。

因此,可以保证的是,iostream最迟在进入main时才能工作没有严格的要求,除非翻译单位包括,否则它们应该更早地工作<iostream>

您已经找到一种规避此问题的方法!

foo()从B.cpp调用时,A.cpp中ios_base::Init包含实例可能已初始化,也可能未初始化。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在C ++(98、11和14)中初始化静态数据成员的正确方法是什么?

具有非静态成员初始化程序的类的C ++ 11聚合初始化

C ++ 11中的数组声明和初始化

C ++ 11和广义初始化程序约定

C ++ 11统一初始化和函数重载

C ++ 11类初始化错误

向量初始化的C ++ 11向量

C ++ 11整数初始化

c ++ 11:枚举成员初始化

C ++ 11 Lambda初始化的惩罚

自动进行C ++ 11初始化

从linux信号处理程序初始化c ++ 11函数静态变量是否安全?

如何在c ++ 11中初始化std :: vector <std :: string>的静态constexpr成员?

c++11:为什么静态 constexpr 的类内初始化不是定义?

C ++ 11函数本地静态const对象的线程安全初始化

C ++ 11中的局部静态变量初始化线程安全吗?

抱歉,未实现:使用C ++ 11的非静态数据成员初始化器

C ++ 11中线程安全的局部静态变量初始化的代价?

非静态数据成员初始化器仅与-std = c ++ 11或-std = gnu ++ 11一起提供

C ++ 11初始化程序列表失败-但仅在长度为2的列表上

在 C++11/17 中的类初始化和直接初始化中。有什么区别?

C ++ 11统一初始化:初始化列表和多参数构造函数之间的歧义?

C ++ / C ++ 11一种有效的方法,使对象的静态数组/矢量通过初始化列表初始化,并支持基于范围的

C ++ 11 / C ++ 14中的自动和括号初始化

c ++ 11全局初始化顺序和thread_local

在C ++ 11中初始化结构的C ++ std :: array

在C ++ 11中非平凡初始化模板类的静态成员而没有clang警告

C ++ 11中的延迟初始化顺序

初始化C ++ 11风格的单例