在C++中,"static initialization fiasco"是否仅影响对另一个模块中定义的对象的数据成员的引用?
In C++, does the "static initialization fiasco" affect merely taking a reference to a data member of an object defined in another module?
是以下示例法律和安全的C ,还是有可能根据链接器决定调用全局对象的构造函数的顺序炸毁?
a.hpp:
class A {
public:
A(int val_);
int val;
};
extern A a;
A.CPP:
#include "a.hpp"
A::A(int val_) : val(val_) {}
A a(1234);
B.CPP:
#include <cassert>
#include "a.hpp"
class B {
public:
B(A &a);
int &ref;
};
B::B(A &a) : ref(a.val) {}
B b(a);
int main(int argc, char **argv) {
assert(b.ref == 1234);
assert(&b.ref == &a.val);
}
我需要在我编写的一些真实代码中进行类似的事情(显然我的A和B类比这个最小的示例要复杂得多,但是他们需要共享的数据成员是普通的旧INT和BOOL)和我宁愿使用引用而不是指针。
是的,这可能会爆炸(无论如何,根据标准),因为 b
的构造函数可以在 a
's之前运行,然后是([class.cdtor]/p1)。..
对于具有非平凡构造函数的对象,指的是任何 构造函数之前的对象的非静态成员或基类 开始执行导致未定义的行为。
您的问题是合法的,但是我认为,在b
实例访问它之前,构建a
的模块将是正确初始化的,如果您在其他不同的情况下构建a
,则应该是正确的。共享对象和类B
与您的示例中的类别A
具有明确的,无圆的依赖关系。这也可以在部署编译器/平台上轻松测试。
如果您仍然不相信,则应该能够在b
之前用免费函数a()
强制 a
的izizialization(首次使用 iDIOM): iDOM):p>标题:
A& a();
汇编单元:
A& a()
{
static A _a;
return _a;
}
然后您用a()
参考_a
。
相关文章:
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- 如何在 c++ 中定义一个将被另一个短语替换的短语?
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- 使用命名空间在另一个".cpp"文件中定义
- C++ 在一个源文件中使用另一个源文件中的矢量定义
- 为什么通过定义另一个指针单元格,整个代码停止工作?
- C++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 如何在一个函数中定义一个变量,并在另一个函数中访问和更改它?(C++)
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- 是否可以使用另一个lua文件中定义的表,该表在当前文件中不需要作为模块
- 在另一个文件中初始化的 extern 数组中未定义的引用
- C++:如何从另一个谓词定义泛型而不是谓词
- 为什么相同的函数签名只有区别,另一个通过 const 获取参数是重新定义?
- 根据是否定义了另一个宏来评估宏
- 如何提前终止在另一个文件中定义的函数?
- 在另一个文件中定义函数后,Visual Studio 无法识别该函数
- 如何在另一个类模板中定义完全专用类的构造函数
- GLM如何在不声明内联函数并在另一个(未连接的?)文件中将其定义的函数逃脱
- 是否可以定义另一个预处理器指令
- 如何定义另一个模板类的内部模板类的构造函数