c++ - 全局范围内变量和函数的递归依赖

标签 c++ initialization language-lawyer

我在玩我的 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/

相关文章:

java - java中数组长度属性

c++ - 为什么这个搜索失败?

java - @PostConstruct 模拟外部最终 bean

c++ - 在 Qt/C++ 中,有没有办法将按钮单击事件列表连接到一个插槽?

c - 嵌套数组的初始化?

c++ - 空的大小是多少?

c++ - 为什么 std::basic_ios 有一个公共(public)构造函数?

c++ - 自动变量创建的顺序是否对应​​声明的顺序?

C++ long long 操作

c++ - 不完整类型 struct std::hash 与 unordered_map 的无效使用,其中 std::pair of enum class 作为键