在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?

本文关键字:定义 另一个 模块 数据成员 引用 对象 static C++ initialization fiasco 是否      更新时间:2023-10-16

是以下示例法律和安全的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

相关文章: