提问人:konchy 提问时间:9/26/2023 最后编辑:Jan Schultkekonchy 更新时间:9/26/2023 访问量:182
全局变量和静态内联数据成员的初始化顺序是否相互保证?
Is the initialization order of global variables and static inline data members relative to each other guaranteed?
问:
下面的代码在同一个翻译单元中,并在 之后定义,为什么不初始化为 “ok” ?A::v
x
A::v
#include <string>
#include <iostream>
std::string foo() {
return "OK";
}
std::string x = foo();
struct A {
static inline std::string v = x;
};
int main() {
std::cout << A::v << std::endl; // didn't print "OK", why?
}
答:
8赞
Brian Bi
9/26/2023
#1
根据 [basic.start.dynamic]/1,具有静态存储持续时间的非内联非模板化非块变量具有“有序”初始化,而具有静态存储持续时间的内联非模板化非块变量具有“部分有序”初始化。
根据 [basic.start.dynamic]/3,在以下情况下,我们只在两个具有静态存储持续时间的非块变量之间提供初始化顺序保证:
- 第一个和第二个变量都具有有序初始化,并且第一个变量的定义先于第二个变量的定义,或者
- 第一个变量具有部分有序初始化,第二个变量具有有序初始化,并且第二个变量的定义前面是第一个变量的定义,或者
- 两个变量都具有部分有序的初始化,并且第二个变量的每个定义前面都有一个第一个变量的定义。
因此,如果在内联变量之前定义了非内联变量,则没有初始化顺序保证。只有当内联变量排在第一位时,我们才有初始化顺序保证。所以在这个代码中,可以初始化之前,导致未定义的行为。v
x
评论
1赞
Jarod42
9/26/2023
虽然不确定 UB,但已经发生了零初始化,所以要么是空的,要么是没有(“常规”SIOF)?v
"OK"s
1赞
Brian Bi
9/26/2023
@Jarod42 不能假定零初始化生成空字符串。 不是轻而易举的可复制的,因此即使您观察到空字符串具有全零位模式,这并不意味着将不同的对象归零会给它相同的值。std::string
std::string
0赞
dfrib
9/26/2023
@Jarod42 对象的零初始化难道不是“不确定”(实现定义)而不是空的吗?std::string
0赞
Oersted
9/26/2023
Gg。对于我的理解,在这种情况下意味着什么?只是在大括号内,有什么包含范围的?block
评论