我在玩我的 C++ 编译器,我注意到一个全局变量的递归依赖,一个函数调用没有被拒绝。例子:
#include <iostream>
int foo();
int t = foo();
int foo()
{
std::cout << "Hello before main: " << t << "\n";
t = 10;
return t + 10;
}
int main()
{
std::cout << "Hello from main.\n";
}
这个编译的程序打印出以下内容:
Hello before main: 0
Hello from main.
所以当我使用声明
t
它依赖于 foo
再次依赖于 t
的函数. C++ 编译器通过本质上具有 t
来打破这个循环。在赋值表达式运行之前初始化为零。这让我很惊讶。这是根据标准的正确行为还是我在这里调用了一些未定义的行为?
最佳答案
Since C++20 , 对象的生命周期从其初始化完成时开始;在访问它之前会导致 UB。
[basic.life]/1 :
... The lifetime of an object of type
T
begins when:
- storage with the proper alignment and size for type
T
is obtained, and- its initialization (if any) is complete (including vacuous initialization) ...
在 C++20 之前,这是定义明确的行为。 Zero initialization首先为 non-local variables 执行.
As described in non-local initialization, static and thread-local variables
that aren't constant-initialized (since C++14)
are zero-initialized before any other initialization takes place. If the definition of a non-class non-local variable has no initializer, then default initialization does nothing, leaving the result of the earlier zero-initialization unmodified.
从标准,[basic.start.static]/2
If constant initialization is not performed, a variable with static storage duration ([basic.stc.static]) or thread storage duration ([basic.stc.thread]) is zero-initialized ([dcl.init]). Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. All static initialization strongly happens before ([intro.races]) any dynamic initialization.
关于c++ - 全局范围内变量和函数的递归依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61241798/