C ++中内部链接的重点是什么

时间:2018-01-11 23:09:24

标签: c++ linkage

据我所知,C ++中的变量有三种可能的链接值 - 没有链接,内部链接和外部链接。

因此,外部链接意味着可以在多个文件中访问变量标识符,而内部链接意味着可以在同一文件中访问它。但内部联系的重点是什么?为什么不只有两个可能的标识符链接 - 没有链接和外部链接?对我来说,似乎全局(或文件)范围和内部联系起着同样的作用。

是否存在内部链接实际上有用且未被全局范围覆盖的用例?

在下面的例子中,我有两段代码 - 第一段链接到static 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定义,内部链接实际上意味着您可以在同一个翻译单元中转发声明变量。但是为什么你甚至需要对文件中已经全局访问的变量这样做呢。这个功能有什么用例吗?

2 个答案:

答案 0 :(得分:7)

每个例子:

外部联系:

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; }

当然,您同意函数foofoo1中的foo2变量必须具有存储空间。这意味着他们可能必须拥有名称,因为汇编程序和链接器的工作方式。这些名称不能冲突,任何其他代码都不应该访问。 C ++标准编码的方式是“没有联系”。还有一些其他情况也可以使用它,但是对于那些使用存储的情况不太明显的事情。 (例如class你可以想象vtable有存储空间,但对于typedef来说,这主要是关于名称访问范围的语言规范细节问题。)

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

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

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

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

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

答案 1 :(得分:-1)

外部链接用于当文件彼此独立编译时(#include .h,.c和.cpp文件不是彼此独立编译的)。外部变量的特殊之处在于它可以在单独编译的文件之间使用。