C++中的全局变量VS文件变量

use*_*064 8 c++ global-variables

C++中全局变量和文件变量之间有什么区别?

谢谢!

小智 15

在C和C++中,您可以通过在声明前面使用static关键字来创建一个全局变量,只能从声明它的文件中访问它.可以从编译到程序中的任何C或C++文件访问不使用static关键字的Globals.

在C++中不推荐使用静态全局方法,而是使用匿名命名空间.放置在匿名命名空间内的任何声明也只能从该文件中访问.


Unc*_*eiv 7

C++程序一次编译一个翻译单元(基本上这意味着每个.cpp文件是独立编译的).

默认情况下,变量都没有const,功能不inlinetypedef■找内部链接:这意味着他们不给其他翻译单元可见.如果其他翻译单元引用具有内部链接的符号(在声明它之后,需要extern变量的关键字),链接器将无法找到它们.

要明确要求内部链接,请使用关键字,static或者更好地使用未命名的命名空间.


str*_*ger 5

注意:这些规则适用于 C++ 和 C 一样,与类/结构/命名空间范围有关。(我没有注意到问题是关于 C++,而不是 C。)

请记住(在大多数情况下)C 源文件被编译为目标文件。目标文件有一个“导出”表,它告诉链接器(在链接时)它提供了什么符号。符号是指代函数或变量(在大多数情况下)的名称(其确切名称取决于 ABI)。

当您在 C 源文件中声明全局变量时,如下所示:

// fileA.c
int hello = 42;

void printMessage() {
    printf("Hello, %d world(s)!\n", hello);
}
Run Code Online (Sandbox Code Playgroud)

helloprintMessage出口。当一个 C 目标文件请求一个名为“ hello”的符号(假设一个简单的 ABI)时,链接器将它与hello导出的fileA.c.

现在是另一种情况。当您像这样声明文件局部变量时:

// fileB.c
static int world = 9001;

static void messagePrint() {
    printf("It's over %d!\n", world);
}
Run Code Online (Sandbox Code Playgroud)

worldmessagePrint没有出口。当 C 目标文件请求名为“ hello”的符号时,链接器无法将其与helloof连接,fileB.c因为在fileB.obj(或其他)中没有关于它的信息。

怎么可能messagePrint知道world呢?两者都在同一个翻译单元中。范围在这里接管。我相信您会通过 Google找到很多关于范围的信息。

(符号名称是否与 C 中的函数/变量名称标准相匹配?我知道它与 C++ 不同(名称修改没有标准化),这就是我首先提到 ABI 的原因。)

((如果 ABI 是正确的术语,甚至?;P))


thi*_*ing 0

唯一的区别是文件变量只能在文件内部访问。但他们却有同样的一生。