在C ++中创建静态全局变量时

时间:2012-12-04 10:14:19

标签: c++ language-lawyer

我知道全局变量是按相同编译单元的声明顺序创建的,并且未在多个编译单元之间定义创建顺序。

我前段时间读过,全局变量是在调用定义它们的编译单元的任何代码之前创建的。这是由标准定义的吗?

示例:

file1.cpp

int f1v1 = f1_1();
int f1v2 = f1_2();

void f1(){...}

int f1_1(){...}
int f1_2(){...}

file2.cpp

static int f2v1 = f2_1();
static int f2v2 = f2_2();

int f2_1(){...}
int f2_2(){...}

的main.cpp

#include "file1.h"
#include "file2.h"

int main()
{
    f1();

    return 0;
}

在这种情况下,在f1_1()之前和f1_2()之前调用f1()的标准是否有保证?完全调用f2_1()f2_2()的标准保证,因为没有调用file2.cpp中定义的函数,而f2v1f2v2在file2.cpp之外是不可见的?

编辑:

当在lib1中编译file1.cpp并且在lib2中编译file2.cpp时,标准是否指定了行为?

2 个答案:

答案 0 :(得分:4)

基于[basic.start.init]:

f1_1()保证在f1_2()之前执行(第2段:“在单个翻译单元中定义的有序初始化的变量应按其在翻译单元中的定义的顺序进行初始化。”)

两者都保证在f1()之前执行(第4段:“如果初始化延迟到主要的第一个语句之后的某个时间点,它应该在第一个odr-use(3.2)之前发生在与要初始化的变量相同的翻译单元中定义的任何函数或变量。“)。

关于f2_1()f2_2(),[basic.stc.static]第2段说“如果具有静态存储持续时间的变量具有初始化或具有副作用的析构函数,则甚至不应该消除它如果它似乎未使用,......“。这意味着如果它们含有副作用,则可以保证它们被调用。

答案 1 :(得分:0)

如果我正确理解您的问题,C ++会按照一个编译单元(即cpp文件)中的声明的顺序保证变量的初始化顺序。编译单元的初始化顺序未定义。

在编译过程中,即使f2_*中的函数未运行,也会调用符合标准file2.cpp函数。但是如果编译器足够智能,它可以完全省略它们,如果它确定生成的程序将行为,就像它符合标准一样。 (即,如果它可以保证超出怀疑的阴影,程序与没有调用这些函数的程序之间的行为就没有差别)