【发布时间】:2023-04-08 07:14:01
【问题描述】:
cppref 说,
如果非内联变量(C++17 起)的初始化延迟发生在 main/thread 函数的第一个语句之后,它发生在任何第一个 odr-use 之前在与要初始化的变量相同的翻译单元中定义的具有静态/线程存储持续时间的变量。
后面给出了一个延迟动态初始化的例子:
// - File 1 -
#include "a.h"
#include "b.h"
B b;
A::A(){ b.Use(); }
// - File 2 -
#include "a.h"
A a;
// - File 3 -
#include "a.h"
#include "b.h"
extern A a;
extern B b;
int main() {
a.Use();
b.Use();
}
评论说:
如果
a在main的第一条语句之后的某个时刻被初始化(它使用File 1中定义的函数,强制其动态初始化运行),那么@ 987654326@ 将在其用于 A::A 之前被初始化
if 的情况为什么会发生? a.Use() odr-use a 因此a 不是必须在此语句之前初始化吗?
【问题讨论】:
-
我很困惑。为什么你认为
a没有初始化? -
@LightnessRacesinOrbit 因为在
a的构造函数中它调用b.Use()。如果a被构造,那么b也将被构造。但是cppref说b被初始化为a.Use(),不是A::A()。 -
@LightnessRacesinOrbit 并且引用的段落说:“如果
a在main的第一条语句之后的某个时刻被初始化”,这意味着a在a.Use()之后被初始化。 -
a.Use()强制“加载”File2(初始化a)。创建a强制“加载”File3(然后初始化b)。 -
@LightnessRacesinOrbit 我认为这个测试用例实际上与 cppref 所说的和原始问题无关。这只是一个未定义的行为,因为未指定不同编译单元中全局变量的初始化顺序。所以在这种情况下,“一个对象将在你调用函数之前被初始化”是不正确的。
标签: c++ initialization language-lawyer one-definition-rule