在静态初始化期间是否保证可用计数
Is cout guaranteed available during static deinitialization?
我有一个准单例类(在大多数情况下,准单例指的是单个对象,它是一个函数静态,但用户也可以为短期使用构造自己的本地副本),我想从它的析构函数中写入cout,并且想知道cout是否保证在程序终止后的静态取消初始化阶段可用。从这个问题看来,答案是肯定的(函数静态初始化对象的析构函数应该从它们被构造时起以相反的顺序调用,应该在cout设置之后),但我想检查一下。
// Count calls to a logging function from some point in our code, to determine
// how many times it gets executed during a run, then report calls at the end
// of the program. A quick-and-dirty way of determining how often we execute
// code.
class callCounter;
class callCounter {
public:
callCounter() : has_calls_(false), counts_() {}
~callCounter () {report(std::cout);}
void logCall(const std::string callSite);
void report(std::ostream &os);
void reset();
static callCounter *theCounter();
private:
typedef std::map<std::string, callCount> COUNTMAP;
bool has_calls_;
COUNTMAP counts_;
};
callCounter *callCounter::theCounter()
{
static callCounter theCounts;
return &theCounts;
}
典型的用法是:
callCounter::theCounter()->logCall("foo");
那么,在析构函数中使用cout是否保证安全(至少就使用cout本身而言——可以说是完全安全的,我应该将报告包装在try块中,以防write抛出异常)?
简短回答:是
长答案:Yes
标准库使用了一些技巧来确保std::cout(和std::cin/std:cerr)在任何其他对象之前可用(但是您必须#include
参见:n3242 (practical the c++ 0x standard Pub: 2011-02-28)
标准iostream对象第二款对象是在类ios_base::Init对象第一次被构造之前或期间被构造的,在任何情况下都是在main函数体开始执行之前。这些对象在程序执行期间不会被销毁。在翻译单元中包含的结果应该像
定义了一个ios_base::Init实例,静态存储时间 。同样,整个程序应该表现得好像至少有一个具有静态存储时间的ios_base::Init实例。
添加高亮显示。
来自n1804(基本上是2003年的标准:Pub: 2005-04-27)
标准iostream对象第二款在相应的宽字符流和窄字符流上的混合操作遵循与在文件上的混合操作相同的语义,如ISO C标准修正案1中规定的那样。对象被构造,关联在类ios_base::Init对象第一次构造之前或期间建立,在任何情况下都是在main主体开始执行之前。280.
不幸的是,使其成为保证的位是在脚注中(这是非规范的(即它不能保证实现者应该尝试和实现的)。
带脚注:
280)静态对象的构造函数和析构函数可以访问这些对象,从stdin读取输入或将输出写入stdout或stderr。
- 添加静态constexpr成员是否会更改结构/类的内存映射
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++:是否可以使用非静态成员变量模板?
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 在 nullptr 上调用无状态类的非静态成员函数是否合法?
- 检查编译时是否存在静态函数
- C++ 返回指向函数内定义的静态数组的指针是否有效?
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 如果包含映射的静态库与可执行文件和动态库链接,静态映射(变量)是否会被多次释放?
- C++编译器是否优化了顺序静态变量读取?
- 返回从字符串文本创建的静态string_view是否安全?
- 这些语句是否等效(静态变量、常量变量和泛型)
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 初始值设定项列表是否足够静态以允许实例化模板?
- 程序如何知道静态变量是否需要初始化?
- 是否使用静态 constexpr 变量 odr?
- 使用静态成员函数而不是普通函数是否有任何开销?
- 如果可能,标准::映射分配是否静态