关于c ++:什么是外部链接和内部链接?

What is external linkage and internal linkage?

我想了解外部联系和内部联系及其区别。

我还想知道

const variables internally link by default unless otherwise declared as extern.


正如Dudewat所说,外部链接意味着符号(函数或全局变量)可以在整个程序中访问,而内部链接意味着只能在一个翻译单元中访问。

您可以使用externstatic关键字显式控制符号的链接。如果未指定链接,则默认链接为extern,对于非const符号为extern,对于const符号为static(内部)。

1
2
3
4
5
6
7
8
9
// in namespace or global scope
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static

// the same goes for functions (but there are no const functions)
int foo(); // extern by default
static int bar(); // explicitly static

注意,不要使用static进行内部链接,最好使用匿名名称空间,也可以将classes放入其中。在C++ 98和C++ 11之间,匿名命名空间的链接已经发生了变化,但主要的原因是它们无法从其他翻译单元访问。

1
2
3
4
namespace {
   int i; // external linkage but unreachable from other translation units.
   class invisible_to_others { };
}


当您编写一个实现文件(.cpp.cxx等)时,编译器会生成一个翻译单元。这是您的实现文件中的对象文件,加上您#included中的所有头文件。

内部链接仅指翻译单元范围内的所有内容。

外部联系是指存在于特定翻译单元之外的事物。换句话说,整个程序都可以访问,它是所有翻译单元(或对象文件)的组合。


  • 默认情况下,全局变量具有外部链接。通过在另一个文件中提供匹配的外部声明,它的作用域可以扩展到不包含它的文件。
  • 全局变量的作用域可以限制为包含声明的文件,方法是在声明前加上关键字static。这些变量被称为具有内部联系。

请考虑以下示例:

1.CPP

1
2
3
4
5
6
7
8
9
10
11
12
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
    int a;
    //...
    f(a);
    //...
    f(a);
    //...
}
  • 函数f的签名将f声明为具有外部链接的函数(默认)。其定义必须在本文件后面或其他翻译单元中提供(见下文)。
  • max定义为整数常量。常量的默认链接是内部的。它的链接用关键字extern更改为external。所以现在可以在其他文件中访问max。
  • n被定义为一个整数变量。在函数体外部定义的变量的默认链接是外部的。
  • 2.CPP

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <iostream>
    using namespace std;

    extern const int max;
    extern int n;
    static float z = 0.0;

    void f(int i)
    {
        static int nCall = 0;
        int a;
        //...
        nCall++;
        n++;
        //...
        a = max * z;
        //...
        cout <<"f() called" << nCall <<" times." << endl;
    }
  • Max声明具有外部链接。max(带有外部链接)的匹配定义必须出现在某些文件中。(如1。CPP)
  • n声明具有外部链接。
  • Z定义为具有内部链接的全局变量。
  • ncall的定义将ncall指定为一个变量,该变量在对函数f()的调用中保留其值。与具有默认自动存储类的局部变量不同,ncall只在程序开始时初始化一次,而不在每次调用f()时初始化一次。存储类说明符static影响局部变量的生存期,而不是其作用域。
  • 注意:关键词static起着双重作用。在全局变量定义中使用时,它指定内部链接。当用于局部变量的定义时,它指定变量的生存期将是程序的持续时间,而不是函数的持续时间。

    希望有帮助!


    在"C"方面(因为静态关键字在‘C’和‘AMP’和‘C++’之间有不同的含义。

    让我们在"c"中讨论不同的范围

    范围:基本上就是我能看到东西的时间和距离。

  • 局部变量:作用域仅在函数内部。它位于RAM的堆栈区域。这意味着每次函数被调用所有变量是该函数的一部分,包括函数参数刚创建的,一旦控件退出功能。(因为每次函数返回时都刷新堆栈)

  • 静态变量:范围是一个文件。文件中的每个位置都可以访问在其中声明。它驻留在RAM的数据段中。自从这只能在文件内部访问,因此只能在内部链接中访问。任何其他文件无法看到此变量。实际上,静态关键字是我们可以引入某种级别的数据或函数的唯一方法藏在"C"里

  • 全局变量:此范围适用于整个应用程序。从每一个应用程序的位置。全局变量也驻留在数据段中因为它可以在应用程序中的每个位置访问,因此外联动装置

  • 默认情况下,所有函数都是全局的。以防万一,如果你需要的话从外部隐藏文件中的某些函数,可以为静态函数的关键字。-)


    在讨论这个问题之前,最好先了解翻译单元、程序和C++的一些基本概念(实际上,链接是其中的一个)。您还必须知道什么是范围。

    我将强调一些要点,特别是那些在以前的答案中遗漏的要点。

    链接是名称的属性,由声明引入。不同的名称可以表示相同的实体(通常是对象或函数)。因此,谈论一个实体的链接通常是无稽之谈,除非您确信该实体只能由某些特定声明(通常是一个声明)中的唯一名称引用。

    注意,对象是一个实体,但变量不是。在讨论变量的链接时,实际上涉及到所表示实体的名称(由特定声明引入)。名称的链接位于三个链接中的一个:无链接、内部链接或外部链接。

    不同的翻译单元可以通过标题/源文件(是的,它是标准的措辞)包含共享相同的声明。因此,您可以在不同的翻译单元中引用相同的名称。如果声明的名称具有外部链接,则该名称引用的实体的标识也将共享。如果声明的名称具有内部链接,则不同翻译单元中的相同名称表示不同的实体,但可以在同一翻译单元的不同范围中引用该实体。如果名称没有链接,则不能从其他作用域引用实体。

    (哎呀……我发现我输入的只是重复标准的措辞……)

    还有一些语言规范中没有涉及的其他混淆点。

  • (名字的)可视性。它也是已声明名称的属性,但其含义与链接不同。
  • (副作用的)可见度。这与本主题无关。
  • (符号的)可视性。这个概念可以由实际的实现使用。在这样的实现中,对象(二进制)代码中具有特定可见性的符号通常是从实体定义映射的目标,其名称在源代码(C++)代码中具有相同的特定链接。然而,通常不能保证一对一。例如,动态库映像中的符号只能从源代码(通常涉及一些扩展,例如__attribute____declspec或编译器选项)内部共享在该映像中,并且该映像不是整个程序或从翻译单元翻译的对象文件,因此没有标准概念可以描述准确地说。由于符号不是C++中的一个规范术语,它只是一个实现细节,即使方言的相关扩展可能已经被广泛采用。
  • 可达性。在C++中,这通常是关于类成员或基类的属性,这又是与主题无关的不同概念。
  • 全球的。在C++中,"Global"指的是全局命名空间或全局命名空间范围。后者大致相当于C语言中的文件范围。在C和C++中,链接与范围无关,虽然作用域(如链接)也与标识符(C)或某些声明引入的名称(C++)紧密相关。
  • 名称空间作用域const变量的链接规则是一种特殊的东西(尤其不同于C语言文件作用域中声明的const对象,它也有标识符链接的概念)。由于ODR是由C++执行的,除了EDCOX1×4函数外,在整个程序中只保留一个相同变量或函数的定义是很重要的。如果没有const的特殊规则,那么一个程序中包含多个翻译单元(或由一个翻译单元包含多次,但很少)的头文件或源文件(通常是"头文件")中带有初始值设定项(例如= xxxconst变量的最简单声明将违反odr,从而使用const变量是不可能替代某些对象宏的。


    我认为C++中的内部和外部链接给出了一个清晰简洁的解释:

    A translation unit refers to an implementation (.c/.cpp) file and all
    header (.h/.hpp) files it includes. If an object or function inside
    such a translation unit has internal linkage, then that specific
    symbol is only visible to the linker within that translation unit. If
    an object or function has external linkage, the linker can also see it
    when processing other translation units. The static keyword, when used
    in the global namespace, forces a symbol to have internal linkage. The
    extern keyword results in a symbol having external linkage.

    The compiler defaults the linkage of symbols such that:

    Non-const global variables have external linkage by default
    Const global variables have internal linkage by default
    Functions have external linkage by default


    链接确定具有相同名称的标识符是否引用相同的对象、函数或其他实体,即使这些标识符出现在不同的翻译单元中。标识符的链接取决于如何声明。有三种类型的连接:

  • 内部链接:标识符只能在翻译单元中看到。
  • 外部链接:在其他翻译单元中可以看到(和引用)标识符。
  • 没有链接:标识符只能在定义它们的作用域中看到。链接不影响作用域
  • C++:您还可以在C++和非C++代码片段之间进行链接,称为语言链接。

    来源:IBM程序链接


    基本上

    • extern linkage变量在所有文件中都可见
    • internal linkage变量在单个文件中可见。

    解释:除非另外声明为外部变量,否则常量变量默认内部链接

  • 默认情况下,全局变量为external linkage
  • 但是,const全局变量是internal linkage
  • 另外,extern const全局变量为external linkage
  • 一个很好的C++链接工具

    http://www. GordsBur.Me/C/C++/Link,2016/03/30/19-34-25-Inthalaland and ExelalalLink


    在C++中

    文件范围内的任何变量,如果不嵌套在类或函数中,则在程序的所有翻译单元中都可见。这被称为外部链接,因为在链接时,链接器在任何地方都可以看到该名称,在该翻译单元之外。

    全局变量和普通函数具有外部联系。

    文件范围内的静态对象或函数名是翻译单元的本地名称。那就是称为内部链接

    链接仅指在链接/加载时具有地址的元素;因此,类声明和局部变量没有链接。