我想了解外部联系和内部联系及其差异。
我也想知道
的含义默认情况下,
const
个变量内部链接,除非另有声明为extern
。
答案 0 :(得分:268)
由于dudewat said 外部链接意味着整个程序都可以访问符号(函数或全局变量),内部链接意味着它只能在一个{ {3}}。
您可以使用extern
和static
关键字明确控制符号的关联。如果未指定链接,则非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
请注意,不要使用static
进行内部关联,最好使用translation unit,您也可以将class
放入其中。匿名命名空间的链接在C ++ 98和C ++ 11之间发生了变化,但主要的是它们无法从其他翻译单元访问。
namespace {
int i; // external linkage but unreachable from other translation units.
class invisible_to_others { };
}
答案 1 :(得分:244)
当您编写实现文件(.cpp
,.cxx
等)时,编译器会生成翻译单元。这是您的实现文件中的目标文件以及#include
中的所有标题。
内部链接指的是翻译单元范围内仅的所有内容。
外部链接是指在特定翻译单元之外存在的内容。换句话说,可通过整个程序访问,这是所有翻译单元(或目标文件)的组合。
答案 2 :(得分:86)
请考虑以下示例:
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
#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;
}
NB:关键字 static 扮演双重角色。在全局变量的定义中使用时,它指定内部链接。当在局部变量的定义中使用时,它指定变量的生命周期将是程序的持续时间而不是函数的持续时间。
希望有所帮助!
答案 3 :(得分:25)
让我们谈谈'C'中的不同范围
范围:基本上我能看到多长时间和多远。
局部变量:范围仅在函数内部。它驻留在RAM的STACK区域。 这意味着每次函数调用所有变量 这是该函数的一部分,包括函数参数 新鲜创造并在控制失效后被摧毁 功能。 (因为每次函数返回时都会刷新堆栈)
静态变量:这是针对文件的范围。它可以在文件中的每个位置访问
在其中声明。它驻留在RAM的DATA段中。以来
这只能在文件中访问,因此只能在INTERNAL链接中访问。任何
其他文件无法看到此变量。实际上STATIC关键字就是
我们可以引入某种程度的数据或功能的唯一方式
藏在'C'
全局变量:这个范围适用于整个应用程序。每个都可以访问 申请的地方。全局变量也驻留在DATA段中 因为它可以在应用程序的每个位置访问,因此 EXTERNAL Linkage
默认情况下,所有功能都是全局的。万一,如果你需要 从外部隐藏文件中的一些函数,可以为静态添加前缀 函数的关键字。 : - )
答案 4 :(得分:10)
在讨论这个问题之前,最好先了解术语translation unit,program和C ++的一些basic concepts(实际上链接是其中一个)。您还必须知道什么是scope。
我将强调一些关键点,尤其是以前的答案中缺少的那些。
链接是名称的属性,由声明引入。不同的名称可以表示相同的实体(通常是对象或函数)。因此,谈论实体的链接通常是无稽之谈,除非您确定该实体仅由某些特定声明(通常是一个声明)中的唯一名称引用。
注意对象是一个实体,但变量不是。在谈论变量的链接时,实际上是指定实体的名称(由特定声明引入)。名称的链接是三者之一:没有联系,内部联系或外部联系。
不同的翻译单元可以通过标题/源文件共享相同的声明(是的,它是标准的措辞)包含。因此,您可以在不同的翻译单元中引用相同的名称。如果声明的名称具有外部链接,则名称引用的实体的标识也是共享的。如果声明的名称具有内部链接,则不同翻译单元中的相同名称表示不同的实体,但您可以在同一翻译单元的不同范围内引用该实体。如果名称没有链接,则您根本无法从其他范围引用该实体。
(哎呀......我发现我输入的内容有点只是重复the standard wording ...)
还有一些其他令人困惑的问题没有被语言规范所涵盖。
__attribute__
或__declspec
)或编译器选项的内部共享,并且图像是不是整个程序或从翻译单元翻译的目标文件,因此没有标准概念可以准确地描述它。由于符号在C ++中不是一个规范性术语,它只是一个实现细节,即使方言的相关扩展可能已被广泛采用。 linkage rule of namespace scope const
variable是特殊的(特别是与C语言文件范围中声明的const
对象不同,它也具有标识符链接的概念)。由于ODR由C ++强制执行,it is important to keep no more than one definition of the same variable or function occurred in the whole program except for inline
functions。如果没有const
这样的特殊规则,则在标头或源文件(通常是&#34;头文件&中)中使用初始值设定项(例如const
)的= xxx
变量的最简单声明#34;)由多个翻译单元包含(或由一个翻译单元不止一次包括,但很少)包含在程序中将违反ODR,这使得const
变量可以替换某些类似对象的宏。
答案 5 :(得分:5)
我认为Internal and External Linkage in C++给出了一个清晰简洁的解释:
翻译单元是指实现(.c / .cpp)文件和所有文件 它包含的头文件(.h / .hpp)。如果是对象或函数里面 这样的翻译单元有内部联系,那就是具体的 符号仅对该转换单元中的链接器可见。如果 一个对象或函数有外部链接,链接器也可以看到它 处理其他翻译单位时。 static关键字,使用时 在全局命名空间中,强制符号具有内部链接。该 extern关键字导致符号具有外部链接。
编译器默认符号链接,以便:
非const全局变量默认具有外部链接
Const全局变量默认具有内部链接 默认情况下,函数具有外部链接
答案 6 :(得分:4)
<强>基本上强>
extern linkage
变量在所有文件中都可见internal linkage
变量在单个文件中可见。解释:const变量默认在内部链接,除非另有声明为extern
external linkage
const
全局变量为internal linkage
extern const
全局变量为external linkage
关于C ++中链接的非常好的材料
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
答案 7 :(得分:4)
链接确定具有相同名称的标识符是否引用相同的对象,函数或其他实体,即使这些标识符出现在不同的转换单元中也是如此。标识符的链接取决于它的声明方式。 有三种类型的联系:
仅限C ++ :您还可以在C ++和非C ++代码片段之间建立链接,称为语言链接。
答案 8 :(得分:0)
在C ++中
文件范围内且未嵌套在类或函数内的任何变量在程序的所有翻译单元中均可见。之所以称为外部链接,是因为链接时该名称对于该翻译单元外部的所有链接器都是可见的。
全局变量和普通函数具有外部链接。
文件范围内的静态对象或函数名称对于翻译单位而言是本地的。那是 称为内部链接
链接仅指在链接/加载时具有地址的元素。因此,类声明和局部变量没有链接。