C++中静态变量的存储位置是什么时候确定的?

When is the storage location of static variables in C++ determined?

我有以下简单程序:

int main()
{
    int x = 5;
    static int y = x;
    return (0);
}

用 gcc 编译它时,static int y = x; 行产生错误,因为“初始化器元素不是常量”。我假设这是由于 y 是一个静态变量,其存储位置 (data/bss) 和初始值需要在编译时知道。

然而,当使用 g++ 编译时,我没有收到任何错误并且程序运行良好(打印 y 打印 5)。

我的问题是:

  1. 我的假设正确吗?
  2. 如果是这样,为什么可以在 c++ 中对静态变量进行这样的初始化?

您的程序在 C++ 中的格式良好,因为具有静态存储持续时间的局部变量不是在启动期间初始化的(常量表达式有一些例外;在本例中不适用),而是在第一次控制通过它们的声明时,此时包含局部非静态变量 x 的初始化表达式随时可用。

引用cppreference / Storage duration - Static local variables[强调我的]

Variables declared at block scope with the specifier static or thread_local (since C++11) have static or thread (since C++11) storage duration but are initialized the first time control passes through their declaration (unless their initialization is zero- or constant-initialization, which can be performed before the block is first entered). On all further calls, the declaration is skipped.

但是,C 中的静态初始化不遵循相同的规则;来自 cppreference / C language - Initialization:

When initializing an object of static or thread-local storage duration, every expression in the initializer must be a constant expression or string literal.

因此你的程序在 C 中的格式不正确。

在 C++ 中,static local variables 仅在控件第一次通过其声明时初始化一次。对于这种情况,ymain() 被调用后被初始化,并且 x 已经用值 5 初始化,然后 y 被初始化为 5 也是

are initialized the first time control passes through their declaration

在 C 中,static variables 在程序启动之前初始化,即在调用 main() 之前; y 无法从 main() 中的局部变量 x 初始化。

Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

我猜这是对 https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables

的不同编译器解释

通常,您只能将静态值分配给静态变量。这包括可执行文件的 .data 部分(例如,所有 char*/c 风格的字符串本质上都是静态的)。

因为 x 不是一个静态值,gcc 的抱怨是正确的。 G++ 是 c++ 编译器,因此与默认为 C 的 gcc 有不同的实现。