C++ c++;“中的初始化静态变量”;“本地范围”;

C++ c++;“中的初始化静态变量”;“本地范围”;,c++,compilation,C++,Compilation,静态变量在程序开始时初始化,如中所述,静态变量的初始化顺序未定义。因此,用另一个静态变量初始化一个静态变量可能会导致程序崩溃 函数中声明的“局部”静态变量也是这样吗 使用全局声明的静态变量初始化“局部”静态变量是否安全 如果我在同一个局部范围内有几个静态变量,那么使用早期声明的变量来初始化晚期声明的变量安全吗?一个具有静态存储持续时间的变量,其中初始值在编译时已知,或者是静态初始化的,并在其他所有变量之前初始化(在C++11和更旧的标准版本中,零初始化先于常量初始化)。毕竟,如果编译器和链接器在

静态变量在程序开始时初始化,如中所述,静态变量的初始化顺序未定义。因此,用另一个静态变量初始化一个静态变量可能会导致程序崩溃

函数中声明的“局部”静态变量也是这样吗

使用全局声明的静态变量初始化“局部”静态变量是否安全


如果我在同一个局部范围内有几个静态变量,那么使用早期声明的变量来初始化晚期声明的变量安全吗?

一个具有静态存储持续时间的变量,其中初始值在编译时已知,或者是静态初始化的,并在其他所有变量之前初始化(在C++11和更旧的标准版本中,零初始化先于常量初始化)。毕竟,如果编译器和链接器在编译时确切地知道该变量的值,为什么他们不将该值放在那里呢

静态初始化的变量不是问题。如果您指定一个常量或零,则变量不依赖于任何其他内容。这就剩下动态初始化,如果我正在阅读[basic.start.static]在C++标准中,静态初始化在任何一个动态初始化之前都会发生。问题是动态初始化变量,静态存储持续时间在多个翻译单元之间交互。您无法保证转换单元的初始化顺序

函数中声明的“局部”静态变量也是这样吗

否。
静态
局部变量具有定义良好的初始初始化顺序。动态初始化将在首次使用时发生,并且它们不能在转换单元之间拆分,这消除了非局部初始化顺序中的模糊性

如果我在同一个局部范围内有几个静态变量,那么使用早期声明的变量来初始化晚期声明的变量安全吗

是的。同样,我们有一个定义良好的初始化顺序。动态初始化的变量将按顺序初始化,静态初始化的变量已经初始化。你可以用一个线程来搞乱这一点,但是C++11最好确保一个线程不能中断静态变量的初始化。如果一个线程中断即使初始化两个静态变量,安全与否也取决于您,但第一个变量仍将在第二个变量之前初始化

使用全局声明的静态变量初始化“局部”静态变量是否安全

不一定。非局部变量在
main
之前分配和初始化,因此通常在您有机会调用包含静态局部变量的函数之前,它们已初始化并准备好使用

但是,如果使用一个包含静态变量的函数进行初始化,该静态变量依赖于来自不同转换单元的变量,那么该如何初始化呢

在A.cpp中说我们有

int A_variable  = something_dynamic();
在B.cpp中,我们有

int func()
{
static int local_static=一个_变量;
返回本地_static;
}
int B_变量=func();

B_变量
的初始化可能发生在
A_变量
的初始化之前。这将调用
func
并将
local_static
设置为
B_变量
中尚未定义的值。oops.

当执行到达该线性静态存储时,将初始化具有动态初始化的局部静态不是使用单个转换单元定义的本地变量的持续时间变量将按照它们在转换单元中定义的顺序创建和销毁。只有当您有多个转换单元和静态存储持续时间变量(取决于另一个转换单元中的静态存储持续时间变量)时,才会出现链接中描述的问题翻译单元,因为您无法控制将首先初始化哪个翻译单元。这不是函数中静态变量的问题。首先,函数不能跨多个翻译单元拆分。@user4581301您的第一句话仅适用于动态初始化。静态初始化首先发生,例如在文件范围
inta=foo();intb=5;intc=bar();
b
在执行
foo
时保证有值
5
,谢谢,@M.M我怀疑类似的事情(如果编译器知道该变量中的内容,为什么不在编译时将其烧掉?)但是我找不到证实。现在我花了更多的时间,我对我提出的答案做了一些修正。