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

  1. i is initialized to 0.
  2. i is 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;`

以上是在C++中,用自身初始化全局变量是否具有未定义的行为?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>