acm*_*acm 10 c++ static initialization undefined-behavior c++11
请考虑以下内容,其中我们在不同的转换单元中有两个文件范围的对象,这是通过初始化顺序fiasco的未定义行为的常规设置:
a.hpp:
struct thing {
public:
thing(int value);
~thing();
int value() const;
static int count();
private:
int _value;
};
Run Code Online (Sandbox Code Playgroud)
a.cpp:
#include "a.hpp"
#include <atomic>
namespace {
std::atomic<int> things;
}
thing::thing(int value) : _value(value) {
++things;
}
thing::~thing() {
--things;
}
int thing::value() const {
return _value;
}
int thing::count() {
return things.load();
}
Run Code Online (Sandbox Code Playgroud)
b.cpp:
#include <iostream>
#include "a.hpp"
namespace {
thing static_thing(42);
}
void foo() {
std::cout << static_thing.value() << ' ' << thing::count() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这是代码受制于文件之间的初始化顺序的悲剧范围的原子things在a.cpp和文件作用域static_thing的b.cpp?如果没有,为什么不呢?特别是,std :: atomic有什么特别的东西可以删除原本清楚的init命令惨败?是否有一个特定的概念可以命名为使用静态断言强制执行此操作?就像是:
static_assert(std::is_trivial<decltype(things)>::value, "file static counter is not trivial");
Run Code Online (Sandbox Code Playgroud)
如果没有std::is_trivial,是否有另一个概念和相关的类型特征更好地模拟这个?
相反,是否存在去初始化惨败?同样的问题,如果是,为什么,或为什么不.
我对 C++“初始化顺序惨败”的理解是,它仅适用于需要在运行时调用构造函数的情况。如果代码可以将内存位置初始化为固定值,则该值会.data像其他预初始化 POD(普通 Ol' 数据)一样被放入“初始化数据”链接器部分 ( ) 中,并且有没有惨败。
我建议 anatomic满足这个标准。
| 归档时间: |
|
| 查看次数: |
140 次 |
| 最近记录: |