在C++中,用自身初始化全局变量是否具有未定义的行为?
int i = i;
int main() {
int a = a;
return 0;
}
int a = a肯定有未定义的行为 (UB),关于它的更多细节在
读取未初始化的值总是未定义的行为吗?或者有例外吗?.
但是呢int i = i?在 C++ 中,我们可以为全局变量分配非常量值。i在遇到声明之前声明并零初始化(因为它具有文件范围)。在这种情况下,我们将0在定义的后面分配给它。可以说这没有 UB 吗?
回答
令人惊讶的是,这并不是未定义的行为。
静态初始化 [basic.start.static]
Constant initialization is performed if a variable or temporary object
with static or thread storage duration is constant-initialized. If
constant initialization is not performed, a variable with static
storage duration or thread storage duration is zero-initialized.
Together, zero-initialization and constant initialization are called
static initialization; all other initialization is dynamic
initialization. All static initialization strongly happens before any
dynamic initialization.
Important parts bold-faced. "Static initialization" includes global variable initialization, "static storage duration" includes global variables, and the above clause is applicable here:
int i = i;
This is not constant-initialization. Therefore, zero-initialization is done according to the above clause (for basic integer types zero-initialization means, unsurprising, that it's set to 0). The above clause also specifies that zero initialization must take place before dynamic initialization.
So, what happens here:
iis initialized to 0.iis then dynamically initialized, from itself, so it still remains 0.
- That's hilarious. This lets you create a non-constructible object! `struct S { S() = delete; } s = s;`
- @RaymondChen Actually useful for pre C++20 captureless lambdas, which don't have a default constructor: https://stackoverflow.com/a/57012585/1896169 .
-
How would that change for global alias ?
`int & i = i;`