C++内部联动有什么意义

What is the point of internal linkage in C++

本文关键字:什么 内部 C++      更新时间:2023-10-16

我知道C++变量有三种可能的链接值 - 无链接,内部链接和外部链接。

因此,外部链接意味着变量标识符可以在多个文件中访问,内部链接意味着它可以在同一文件中访问。但内部联动的意义何在呢?为什么不为一个标识符建立两种可能的联系——没有联系和外部联系?对我来说,全球(或文件)范围和内部链接似乎具有相同的目的。

是否有任何用例表明内部链接实际上有用,但全球范围未涵盖?

在下面的示例中,我有两段代码 - 第一段链接到静态 int i11(具有内部链接),第二段没有。 两者都做同样的事情,因为 main 由于其文件范围已经可以访问变量 i11。那么为什么要有一个单独的链接,称为内部链接。

static int i11 = 10;
int main()
{
extern int i11;
cout << ::i11;
return 0;
}

给出的结果与

static int i11 = 10;
int main()
{
cout << ::i11;
return 0;
}

编辑:为了更加清晰,根据下面的HolyBlackCat的定义,内部链接实际上意味着您可以在同一翻译单元中转发声明变量。但是为什么您甚至需要为文件中已经全局可访问的变量执行此操作..此功能是否有任何用例?

每个示例:

外部链接:

foo.h
extern int foo; // Declaration
foo.cpp
extern int foo = 42; // Definition
bar.cpp
#include "foo.h"
int bar() { return foo; } // Use

内部联动:

foo.cpp
static int foo = 42; // No relation to foo in bar.cpp

bar.cpp
static int foo = -43; // No relation to foo in foo.cpp

无链接:

foo.cpp
int foo1() { static int foo = 42; foo++; return foo; }
int foo2() { static int foo = -43; foo++; return foo; }

您肯定会同意函数中的foo变量foo1foo2必须具有存储。这意味着由于汇编器和链接器的工作方式,它们可能必须具有名称。这些名称不能冲突,并且不应由任何其他代码访问。C++标准对此进行编码的方式是"无链接"。还有其他一些情况也使用它,但对于存储用途不太明显的事情。(例如,对于class你可以想象vtable有存储,但对于typedef来说,这主要是关于名称访问范围的语言规范细节问题。

C++指定了一个最小公分母链接模型,该模型可以映射到实际平台上实际链接器的更丰富的模型上。在实践中,这是非常不完美的,许多实际系统最终使用属性、编译指示或编译器标志来更好地控制链接类型。为了做到这一点并仍然提供一种相当有用的语言,人们进入了名称重整和其他编译器技术。如果C++尝试提供更大程度的编译代码互操作,例如Java或.NET虚拟机,那么该语言很可能会获得对链接的更清晰,更精细的控制。

编辑:为了更清楚地回答这个问题...该标准必须定义它如何工作,以访问源语言中的标识符和链接编译代码。定义必须足够强大,以便正确编写的代码永远不会对未定义或乘法定义的事物产生错误。当然有比C++更好的方法来做到这一点,但它在很大程度上是一种进化的语言,规范在某种程度上受到编译基质的影响。实际上,三种不同类型的联系是:

  • 外部链接:整个程序同意此名称,并且可以在任何可见声明的地方访问它。
  • 内部链接:单个文件同意此名称,并且可以在声明可见的任何范围内访问它。
  • 无链接:名称仅适用于一个范围,并且只能在此范围内访问。

在程序集中,这些声明倾向于映射到全局声明、文件本地声明和具有合成唯一名称的文件本地声明。

它也与在程序的不同部分以不同链接声明相同名称的情况以及确定extern int foo从给定位置引用的内容有关。

外部链接适用于文件彼此独立编译的情况(#included.h、.c 和 .cpp 文件不是彼此独立编译的)。extern 变量的特殊之处在于它可以在单独编译的文件之间使用。