程序如何知道静态变量是否需要初始化?

How does program know if static variable needs to be initialized?

本文关键字:初始化 是否 变量 何知道 静态 程序      更新时间:2023-10-16

如标题所示 - 程序如何知道,第二次调用函数时foo已经初始化:

int getFoo()
{
static int foo = 30;
return foo;
}
int main()
{
getFoo();
getFoo();
}

我想知道,程序是否存储了一些关于哪个静态变量已经初始化的附加信息。

编辑
我在这里找到了一个答案:
为什么本地静态对象的初始化使用隐藏的防护标志?
就像我猜的那样 - 大多数编译器存储额外的"保护变量"。

看看 [stmt.dcl]/4:

    具有静态存储持续时间
  1. 或线程存储持续时间的块范围变量的动态初始化在控件第一次通过其声明时执行;此类变量在其初始化完成后被视为已初始化。如果初始化通过引发异常退出,则初始化未完成,因此下次控件进入声明时将再次尝试初始化。如果控件在初始化变量时同时输入声明,则并发执行应等待初始化完成。94 如果在初始化变量时控件以递归方式重新输入声明,则行为是未定义的。

在这里你必须小心。 原始static在编译时初始化(只要初始化值是编译时常量,正如 Peter 指出的那样(,所以在你的示例中,GetFoo实际上只是返回一个常量。

然而。。。

初始化对象(或通过调用函数初始化原语(的static在首次输入声明它们的作用域时执行所述初始化。

此外,从 C++ 11 开始,这必须以线程安全的方式完成,这会生成大量额外的代码(尽管在第一次通过后没有太多的运行时开销(,这可能是一个问题,例如,代码大小通常很重要的微控制器。

下面是一个具体的例子:

#include <iostream>
struct X
{
X () { std::cout << "Initialising mn"; m = 7; }
int m;
};
void init_x ()
{
static X x;
}
int main () {
std::cout << "main calledn";
init_x ();
std::cout << "init_x returnedn";
}

输出:

main called
Initialising m
init_x returned

现场演示:https://wandbox.org/permlink/NZApcYYGwK36vRD4

生成的代码:https://godbolt.org/z/UUcL9s