当静态链接库时静态变量会发生什么

What happens to static variables when libraries are statically linked

假设我有实现单例模式的库 (A)(它在实现中有一个静态变量)。

(A)库被编译为静态库。

现在,假设我的项目中有:

最后,我的单例真的是单例吗(我的变量真的是静态的)? (B)(C) 是否从 (A) 中获取相同的静态变量(它是 unic)?或者 (A) 被静态链接两次嵌入 (A) 的代码两次以我的来自 (A) 的静态变量在最终二进制代码中出现两次而告终?那么如果(B)修改静态变量值,(C)会不会看到变化?

注意:我在将项目的库更改为静态链接而不是动态链接时遇到过这种情况。我只是想知道我是否做错了什么,或者这是否是一种正常的已知行为。

静态链接库,与静态变量无关

静态变量,在当前编译范围外不可见(.o 文件中未创建符号名称,因此其他 .o 文件无法通过符号名称找到该变量)。

这意味着变量

静态整数 foo;可以存在于每一个编译作用域中,并且每一个都是uniqe

你的静态变量真的是静态的。我怀疑即使 (B) 链接 (A),(B) 也没有获取它自己的 (A) 副本 - 相反它包含应该链接 (A) 的信息。

但是可以在两个库中使用静态变量编译相同的源代码 - 例如:

test.cpp:

int g_myGlobal = 23;

并在 (A) 和 (B) 静态库中编译它,但随后在链接整个应用程序或 dll 时 - 您将收到关于双重定义静态变量的链接器错误。

如果您使用 static 关键字声明变量:

test.cpp:

static int g_myGlobal = 23;

然后,如果从 (A) 和 (B) 链接相同的源代码 - 它将编译和链接正常,但结果你将有两个 g_myGlobal 变量实例(可以是偶数不同)。

首先:

(B) 和 (C) 不 link 反对 (A)。编译静态库,而不是 linked。 在构建 (B) 和 (C) 时,编译器可能需要查看 (A) 中的某些定义,但不要将其与 linking 混淆。 (A) 的代码未复制到 (B) 或 (C) 中。

其次:

(D) 将不得不 link 对抗 (A)、(B) 和 (C)。这意味着您在 (D) 中只能得到一份 (A) 的代码。

动态-link Library/Shared 对象:

如果 (B) 和 (C) 改为 dlls/sos,这当然会有所不同。 Dll 是 linked,因此如果您将 (B) 和 (C) 构建为 dll,并且 link 它们针对 (A),那么您将在 (B) 中分别拥有 (A) 代码的副本和 (C).

Are (B) and (C) seing the same static variable from (A)

这取决于您的变量是否具有 external or internal linkage。以下头文件包含一个带有内部 linkage 的静态 int 变量。这意味着包含此文件的每个翻译单元都将获得自己的 myVariable.

副本
//MyHeader.h
#pragma once
static int myVariable = 0;