10

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

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

例子:

文件1.cpp

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

void f1(){...}

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

文件2.cpp

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

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

主文件

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

int main()
{
    f1();

    return 0;
}

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

编辑:

当file1.cpp在lib1中编译,file2.cpp在lib2中编译时,标准规定的行为是什么?

4

2 回答 2

4

基于[basic.start.init]:

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

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

关于f2_1()and f2_2(),[basic.stc.static]para.2 说“如果具有静态存储持续时间的变量具有初始化或具有副作用的析构函数,即使它看起来未使用,也不应被消除,......”。这意味着如果它们包含副作用,它们肯定会被调用。

于 2012-12-04T10:30:38.870 回答
0

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

在编译过程中,会调用符合标准f2_*的函数,即使里面的函数没有运行。但是,如果编译器足够聪明,它可以完全忽略它们,如果它确定生成的程序会像符合标准一样行事。(即,如果它可以毫无疑问地保证在调用这些函数的程序和不调用这些函数的程序之间的行为没有区别)file2.cpp

于 2012-12-04T10:31:22.197 回答