C++ 什么是外部联动和内部联动?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1358400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:41:32  来源:igfitidea点击:

What is external linkage and internal linkage?

c++c++-faq

提问by rkb

I want to understand the external linkage and internal linkage and their difference.

我想了解外部链接和内部链接以及它们的区别。

I also want to know the meaning of

我也想知道什么意思

constvariables internally link by default unless otherwise declared as extern.

const默认情况下,变量在内部链接,除非另外声明为extern.

采纳答案by dudewat

When you write an implementation file (.cpp, .cxx, etc) your compiler generates a translation unit. This is the source file from your implementation plus all the headers you #included in it.

当您编写实现文件(.cpp.cxx等)时,您的编译器会生成一个翻译单元。这是来自您的实现的源文件以及您#include在其中输入的所有标头。

Internal linkagerefers to everything only in scope of a translation unit.

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

External linkagerefers to things that exist beyond a particular translation unit. In other words, accessible through the whole program, which is the combination of all translation units (or object files).

外部链接是指存在于特定翻译单元之外的事物。换句话说,可以通过整个程序访问,这是所有翻译单元(或目标文件)的组合。

回答by Motti

As dudewat saidexternallinkage means the symbol (function or global variable) is accessible throughout your program and internallinkage means that it's only accessible in one translation unit.

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

You can explicitly control the linkage of a symbol by using the externand statickeywords. If the linkage isn't specified then the default linkage is externfor non-constsymbols and static(internal) for constsymbols.

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

// 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 

Note that instead of using staticfor internal linkage it is better to use anonymous namespacesinto which you can also put classes. The linkage for anonymous namespaces has changed between C++98 and C++11 but the main thing is that they are unreachable from other translation units.

请注意,static与其用于内部链接,不如使用匿名命名空间,您也可以将classes放入其中。匿名命名空间的链接在 C++98 和 C++11 之间发生了变化,但主要是其他翻译单元无法访问它们。

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

回答by Rajendra Uppal

  • A global variable has external linkageby default. Its scope can be extended to files other than containing it by giving a matching externdeclaration in the other file.
  • The scope of a global variable can be restricted to the file containing its declaration by prefixing the declaration with the keyword static. Such variables are said to have internal linkage.
  • 默认情况下,全局变量具有外部链接。通过extern在另一个文件中给出匹配的声明,它的范围可以扩展到包含它以外的文件。
  • 通过在声明前加上关键字 ,可以将全局变量的范围限制为包含其声明的文件static。据说这样的变量具有内部联系

Consider following example:

考虑以下示例:

1.cpp

1.cpp

void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
    int a;
    //...
    f(a);
    //...
    f(a);
    //...
}
  1. The signature of function fdeclares fas a function with external linkage(default). Its definition must be provided later in this file or in other translation unit (given below).
  2. maxis defined as an integer constant. The default linkage for constants is internal. Its linkage is changed to external with the keyword extern. So now maxcan be accessed in other files.
  3. nis defined as an integer variable. The default linkage for variables defined outside function bodies is external.
  1. 函数的签名f声明f为具有外部链接的函数(默认)。它的定义必须稍后在此文件或其他翻译单元中提供(如下所示)。
  2. max定义为整数常量。常量的默认链接是internal。其链接通过关键字 更改为外部链接extern。所以现在max可以在其他文件中访问。
  3. n定义为整数变量。在函数体外部定义的变量的默认链接是external

2.cpp

2.cpp

#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;
}
  1. maxis declared to have external linkage. A matching definition for max(with external linkage) must appear in some file. (As in 1.cpp)
  2. nis declared to have external linkage.
  3. zis definedas a global variable with internal linkage.
  4. The definition of nCallspecifies nCallto be a variable that retains its value across calls to function f(). Unlike local variables with the default auto storage class, nCallwill be initialized only once at the start of the program and not once for each invocation of f(). The storage class specifier staticaffects the lifetime of the local variable and not its scope.
  1. max被声明为具有外部链接max(带有外部链接)的匹配定义必须出现在某个文件中。(如在 1.cpp 中)
  2. n被声明为具有外部链接
  3. z定义为具有全局变量内部连接
  4. 的定义nCall指定nCall为一个变量,在调用 function 时保留其值f()。与具有默认自动存储类的局部变量不同,nCall它只会在程序开始时初始化一次,而不是每次调用f(). 存储类说明符static影响局部变量的生命周期,而不是其作用域。

NB:The keyword staticplays a double role. When used in the definitions of global variables, it specifies internal linkage. When used in the definitions of the local variables, it specifies that the lifetime of the variable is going to be the duration of the program instead of being the duration of the function.

注意:关键字static起着双重作用。当用于全局变量的定义时,它指定内部链接。当在局部变量的定义中使用时,它指定变量的生命周期将是程序的持续时间而不是函数的持续时间。

Hope that helps!

希望有帮助!

回答by Libin Jose

In terms of 'C' (Because static keyword has different meaning between 'C' & 'C++')

就'C'而言(因为静态关键字在'C'和'C++'之间具有不同的含义)

Lets talk about different scope in 'C'

让我们谈谈'C'中的不同范围

SCOPE: It is basically how long can I see something and how far.

SCOPE:基本上是我能看到多长时间和多远。

  1. Local variable : Scope is only inside a function. It resides in the STACK area of RAM. Which means that every time a function gets called all the variables that are the part of that function, including function arguments are freshly created and are destroyed once the control goes out of the function. (Because the stack is flushed every time function returns)

  2. Static variable: Scope of this is for a file. It is accessible every where in the file
    in which it is declared. It resides in the DATA segment of RAM. Since this can only be accessed inside a file and hence INTERNAL linkage. Any
    other files cannot see this variable. In fact STATIC keyword is the only way in which we can introduce some level of data or function
    hiding in 'C'

  3. Global variable: Scope of this is for an entire application. It is accessible form every where of the application. Global variables also resides in DATA segment Since it can be accessed every where in the application and hence EXTERNAL Linkage

  1. 局部变量:作用域仅在函数内部。它位于 RAM 的堆栈区。这意味着每次函数被调用时,作为该函数一部分的所有变量,包括函数参数,都是新创建的,一旦控制权离开函数就会被销毁。(因为每次函数返回都会刷新堆栈)

  2. 静态变量:此范围用于文件。它
    在声明它的文件中的每个位置都可以访问。它驻留在 RAM 的 DATA 段中。由于这只能在文件内部访问,因此只能在内部链接中访问。任何
    其他文件都看不到这个变量。事实上,STATIC 关键字是我们可以
    在“C”中引入某种级别的数据或函数隐藏的唯一方法

  3. 全局变量:此范围适用于整个应用程序。它可以从应用程序的任何地方访问。全局变量也驻留在 DATA 段中,因为它可以在应用程序的任何地方访问,因此可以访问 EXTERNAL Linkage

By default all functions are global. In case, if you need to hide some functions in a file from outside, you can prefix the static keyword to the function. :-)

默认情况下,所有函数都是全局的。如果您需要从外部隐藏文件中的某些函数,您可以在函数前加上 static 关键字。:-)

回答by FrankHB

Before talking about the question, it is better to know the term translation unit, programand some basic conceptsof C++ (actually linkage is one of them in general) precisely. You will also have to know what is a scope.

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

I will emphasize some key points, esp. those missing in previous answers.

我会强调一些关键点,尤其是。以前的答案中缺少的那些。

Linkageis a property of a name, which is introduced by a declaration. Different names can denote same entity(typically, an object or a function). So talking about linkageof an entity is usually nonsense, unless you are sure that the entity will only be referred by the unique name from some specific declarations (usually one declaration, though).

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

Note an objectis an entity, but a variableis not. While talking about the linkage of a variable, actually the name of the denoted entity (which is introduced by a specific declaration) is concerned. The linkage of the name is in one of the three: no linkage, internal linkage or external linkage.

请注意,对象是一个实体,但变量不是。说到变量的链接,其实关心的是所指实体的名称(由特定的声明引入)。名称的联动处于以下三种之一:无联动、内部联动或外部联动。

Different translation units can share the same declaration by header/source file (yes, it is the standard's wording) inclusion. So you may refer the same name in different translation units. If the name declared has external linkage, the identity of the entity referred by the name is also shared. If the name declared has internal linkage, the same name in different translation units denotes different entities, but you can refer the entity in different scopes of the same translation unit. If the name has no linkage, you simply cannot refer the entity from other scopes.

不同的翻译单元可以通过头文件/源文件(是的,这是标准的措辞)包含共享相同的声明。因此,您可能会在不同的翻译单元中引用相同的名称。如果声明的名称具有外部链接,则该名称所指的实体的身份也是共享的。如果声明的名称具有内部链接,则不同翻译单元中的相同名称表示不同的实体,但您可以引用同一翻译单元不同范围内的实体。如果名称没有链接,则您根本无法从其他范围引用实体。

(Oops... I found what I have typed was somewhat just repeating the standard wording...)

(糟糕......我发现我输入的内容只是在重复标准措辞......)

There are also some other confusing points which are not covered by the language specification.

还有一些语言规范没有涵盖的其他令人困惑的点。

  1. Visibility (of a name). It is also a property of declared name, but with a meaning different to linkage.
  2. Visibility (of a side effect). This is not related to this topic.
  3. Visibility (of a symbol). This notion can be used by actual implementations. In such implementations, a symbol with specific visibility in object (binary) code is usually the target mapped from the entity definition whose names having the same specific linkage in the source (C++) code. However, it is usually not guaranteed one-to-one. For example, a symbol in a dynamic library image can be specified only shared in that image internally from source code (involved with some extensions, typically, __attribute__or __declspec) or compiler options, and the image is not the whole program or the object file translated from a translation unit, thus no standard concept can describe it accurately. Since symbol is not a normative term in C++, it is only an implementation detail, even though the related extensions of dialects may have been widely adopted.
  4. Accessibility. In C++, this is usually about property of class members or base classes, which is again a different concept unrelated to the topic.
  5. Global. In C++, "global" refers something of global namespace or global namespace scope.The latter is roughly equivalent to file scopein the C language. Both in C and C++, the linkage has nothing to do with scope, although scope (like linkage) is also tightly concerned with an identifier (in C) or a name (in C++) introduced by some declaration.
  1. 可见性(名称)。它也是声明名称的属性,但与链接的含义不同
  2. 可见性(副作用)。这与本主题无关。
  3. 可见性(符号的)。这个概念可以被实际实现使用。在此类实现中,在对象(二进制)代码中具有特定可见性的符号通常是从实体定义映射的目标,其名称在源 (C++) 代码中具有相同的特定链接。但是,通常不能保证一对一。例如,动态库图像中的符号可以指定仅在该图像内部从源代码共享(通常涉及某些扩展,__attribute____declspec) 或编译器选项,并且图像不是整个程序或从翻译单元翻译的目标文件,因此没有标准概念可以准确描述它。由于符号不是 C++ 中的规范术语,它只是一个实现细节,即使方言的相关扩展可能已被广泛采用。
  4. 可访问性。在 C++ 中,这通常是关于类成员或基类的属性,这又是一个与主题无关的不同概念。
  5. 全球的。在 C++ 中,“global”指的是全局命名空间或全局命名空间范围。后者大致相当于C 语言中的文件作用域。在 C 和 C++ 中,链接都与作用域无关,尽管作用域(如链接)也与某个声明引入的标识符(在 C 中)或名称(在 C++ 中)紧密相关。

The linkage rule of namespace scope constvariableis something special (and particularly different to the constobject declared in file scope in C language which also has the concept of linkage of identifiers). Since ODRis enforced by C++, it is important to keep no more than one definition of the same variable or function occurred in the whole program except for inlinefunctions. If there is no such special rule of const, a simplest declaration of constvariable with initializers (e.g. = xxx) in a header or a source file (often a "header file") included by multiple translation units (or included by one translation unit more than once, though rarely) in a program will violate ODR, which makes to use constvariable as replacement of some object-like macros impossible.

命名空间作用域const变量联动规则比较特殊(与constC语言中文件作用域中声明的对象特别不同,后者也有标识符联动的概念)。由于ODR被C ++执行,它保持不超过相同的变量或函数的一个定义发生在除了整个程序是很重要的inline功能。如果没有这样的特殊规则const,则在多个翻译单元(或一个翻译单元多次包含)包含的头文件或源文件(通常为“头文件”)中,最简单地声明const带有初始值设定项(例如= xxx)的变量,虽然很少)在程序中会违反 ODR,这使得使用const变量作为替代某些类对象的宏是不可能的。

回答by Nan Xiao

I think Internal and External Linkage in C++gives a clear and concise explanation:

我认为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/.cpp) 文件和它包含的所有头文件 (.h/.hpp)。如果此类翻译单元内的对象或函数具有内部链接,则该特定符号仅对该翻译单元内的链接器可见。如果一个对象或函数有外部链接,链接器在处理其他翻译单元时也可以看到它。static 关键字在全局命名空间中使用时,强制符号具有内部链接。extern 关键字产生具有外部链接的符号。

编译器默认符号的链接,使得:

非常量全局变量默认有外部链接 const 全局变量默认
有内部链接
函数默认有外部链接

回答by arun pal

Linkage determines whether identifiers that have identical names refer to the same object, function, or other entity, even if those identifiers appear in different translation units. The linkage of an identifier depends on how it was declared. There are three types of linkages:

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

  1. Internal linkage: identifiers can only be seen within a translation unit.
  2. External linkage: identifiers can be seen (and referred to) in other translation units.
  3. No linkage: identifiers can only be seen in the scope in which they are defined. Linkage does not affect scoping
  1. 内部链接:标识符只能在翻译单元内看到。
  2. 外部链接:可以在其他翻译单元中看到(和引用)标识符。
  3. 无链接:标识符只能在定义它们的范围内看到。链接不影响范围

C++ only: You can also have linkage between C++ and non-C++ code fragments, which is called language linkage.

C++ only:您还可以在 C++ 和非 C++ 代码片段之间进行链接,这称为语言链接

Source :IBM Program Linkage

来源:IBM 程序链接

回答by Color

Basically

基本上

  • extern linkagevariable is visible in all files
  • internal linkagevariable is visible in single file.
  • extern linkage变量在所有文件中可见
  • internal linkage变量在单个文件中可见。

Explain: const variables internally link by default unless otherwise declared as extern

说明:const 变量默认内部链接,除非另外声明为 extern

  1. by default, global variable is external linkage
  2. but, constglobal variable is internal linkage
  3. extra, extern constglobal variable is external linkage
  1. 默认情况下,全局变量是 external linkage
  2. 但是,const全局变量是internal linkage
  3. 额外的,extern const全局变量是external linkage

A pretty good material about linkage in C++

关于 C++ 中链接的一个很好的材料

http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/

http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/

回答by Saurabh Raoot

In C++

在 C++ 中

Any variable at file scope and that is not nested inside a class or function, is visible throughout all translation units in a program. This is called external linkagebecause at link time the name is visible to the linker everywhere, external to that translation unit.

文件范围内且未嵌套在类或函数中的任何变量在程序中的所有翻译单元中都是可见的。这称为外部链接,因为在链接时,该名称对链接器在该翻译单元外部的任何地方都是可见的。

Global variables and ordinary functions have external linkage.

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

Staticobject or function name at file scope is local to translation unit. That is called as Internal Linkage

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

Linkage refers only to elements that have addresses at link/load time; thus, class declarations and local variables have no linkage.

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