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

时间:2016-04-28 08:18:29

标签: c++ static static-libraries static-linking

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

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

现在,让我们说一下我的问题:

  • (B),另一个静态库,与(A)静态链接。
  • (C),另一个静态库,与(A)静态链接。
  • (D),一个与(B)(C)相关联的顶级程序。

最后,我的单身人士真的是单身人士(我的变量真的是静态的)吗? (B)(C)是否从(A)获取相同的静态变量(它是unic)吗?或者(A)是否静态链接了两次嵌入式(A)代码的事实两次以最终二进制代码中出现两次(A)的静态变量结束?然后,如果(B)修改了静态变量值,(C)将无法看到更改?

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

3 个答案:

答案 0 :(得分:7)

首先:

(B)和(C)不与(A)相关联。静态库是编译的,而不是链接的。 构建(B)和(C)时,编译器可能需要查看(A)中的某些定义,但不要将其与链接混淆。 (A)代码不会复制到(B)或(C)。

<强>其次:

(D)必须与(A),(B)和(C)联系。这意味着您只能在(D)中获得(A)代码的一个副本。

动态链接库/共享对象:

如果(B)和(C)是dlls / sos,那当然会有所不同。 Dll是链接的,因此如果您将(B)和(C)构建为dll并将它们链接到(A),那么您将在(B)和(C)中分别使用(A)代码的副本。

  

(B)和(C)是否从(A)

中获得相同的静态变量

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

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

答案 1 :(得分:0)

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

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

这意味着变量

static int foo;可以存在于每个编译范围中,每个编译范围都是唯一的

答案 2 :(得分:0)

您的静态变量实际上是静态的。我怀疑,即使(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变量实例(甚至可以是不同的)。