Dan*_*Dan 64 c++ undefined-behavior language-lawyer
int i = i;
int main() {
int a = a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
int a = a肯定有未定义的行为 (UB),关于它的更多细节在
读取未初始化的值总是未定义的行为吗?或者有例外吗?.
但是呢int i = i?在 C++ 中,我们可以为全局变量分配非常量值。i在遇到声明之前声明并零初始化(因为它具有文件范围)。在这种情况下,我们将0在定义的后面分配给它。可以说这没有 UB 吗?
Sam*_*hik 57
令人惊讶的是,这并不是未定义的行为。
静态初始化 [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;
Run Code Online (Sandbox Code Playgroud)
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:
i is initialized to 0.i is then dynamically initialized, from itself, so it still remains 0.该行为可能未定义i,因为根据您阅读标准的方式,您可能会i在其生命周期开始之前阅读。
\n\n\n
[basic.life]/1.2...类型 T 的对象的生命周期从以下时间开始:
\n\xe2\x80\x94 其初始化(如果有)已完成...
\n
正如另一个答案中提到的,i初始化两次:首先静态零初始化,然后i动态初始化。
哪个初始化开始生命周期?第一个还是最后一个?
\n该标准含糊不清,并且其中存在相互矛盾的注释(尽管它们都是非规范性的)。[basic.life]/6首先, (感谢@eerorika )中有一个脚注明确指出动态初始化启动生命周期:
\n\n\n
[basic.life]/6在对象的生命周期开始之前但在对象将占用的存储空间已分配之后26
\n...
\n26) 例如,在动态初始化具有静态存储持续时间的对象之前...
\n
这种解释对我来说最有意义,因为否则在类实例进行动态初始化、建立其不变量(包括标准定义的标准库类)之前访问类实例是合法的。
\n中还有一个相互矛盾的注释[basic.start.static]/3,但该注释比我上面提到的更早。
| 归档时间: |
|
| 查看次数: |
4029 次 |
| 最近记录: |