Mot*_*tti 275
正如dudewat所说, 外部链接意味着符号(函数或全局变量)可以在整个程序中访问,内部链接意味着它只能在一个翻译单元中访问.
您可以使用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
Run Code Online (Sandbox Code Playgroud)
请注意,不要使用static
内部链接,最好使用匿名命名空间,也可以将class
es 放入其中.匿名命名空间的链接在C++ 98和C++ 11之间发生了变化,但主要的是它们无法从其他翻译单元访问.
namespace {
int i; // external linkage but unreachable from other translation units.
class invisible_to_others { };
}
Run Code Online (Sandbox Code Playgroud)
小智 257
当您编写实现文件(.cpp
,.cxx
等)时,编译器会生成一个转换单元.这是您的实现文件中的目标文件以及您#include
在其中的所有标题.
内部链接仅指翻译单元范围内的所有内容.
外部链接指的是存在于特定翻译单元之外的事物.换句话说,可以通过整个程序访问,这是所有翻译单元(或目标文件)的组合.
Raj*_*pal 91
考虑以下示例:
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
Run Code Online (Sandbox Code Playgroud)
#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;
}
Run Code Online (Sandbox Code Playgroud)
注意:关键字static扮演双重角色.在全局变量的定义中使用时,它指定内部链接.当在局部变量的定义中使用时,它指定变量的生命周期将是程序的持续时间而不是函数的持续时间.
希望有所帮助!
Lib*_*ose 27
让我们谈谈'C'中的不同范围
范围:基本上我能看到多长时间和多远.
局部变量:范围仅在函数内部.它驻留在RAM的STACK区域.这意味着每次调用一个函数时,所有作为该函数一部分的变量,包括函数参数都是新创建的,并且一旦控件退出函数就会被销毁.(因为每次函数返回时都会刷新堆栈)
静态变量:这是针对文件的范围.它可以在
声明它的文件中的每个位置访问.它驻留在RAM的DATA段中.因为这只能在文件内访问,因此只能在INTERNAL链接中访问.任何
其他文件都看不到此变量.事实上,STATIC关键字是我们可以
在'C'中引入某种级别的数据或函数隐藏的唯一方法
全局变量:这个范围适用于整个应用程序.它可以从应用程序的每个位置访问.全局变量也驻留在DATA段中,因为它可以在应用程序的每个位置访问,因此可以访问EXTERNAL Linkage
默认情况下,所有功能都是全局 如果您需要从外部隐藏文件中的某些函数,可以将static关键字作为前缀添加到函数中.:-)
Fra*_*kHB 12
在讨论这个问题之前,最好先了解术语翻译单元,程序和C++的一些基本概念(实际上链接是一般的).您还必须知道什么是范围.
我会强调一些关键点,尤其是 以前的答案中缺少的那些.
Linkage是名称的属性,由声明引入.不同的名称可以表示相同的实体(通常是对象或函数).因此,谈论实体的链接通常是无稽之谈,除非您确定该实体仅由某些特定声明(通常是一个声明)中的唯一名称引用.
注意,对象是实体,但变量不是.在谈论变量的链接时,实际上是指定实体的名称(由特定声明引入).名称的链接是三者之一:没有联系,内部联系或外部联系.
不同的翻译单元可以通过标题/源文件(是的,它是标准的措辞)包含来共享相同的声明.因此,您可以在不同的翻译单元中引用相同的名称.如果声明的名称具有外部链接,则名称引用的实体的标识也是共享的.如果声明的名称具有内部链接,则不同翻译单元中的相同名称表示不同的实体,但您可以在同一翻译单元的不同范围内引用该实体.如果名称没有链接,则您根本无法从其他范围引用该实体.
(哎呀......我发现我输入的内容有点只是重复标准的措辞 ......)
还有一些其他混淆点,语言规范没有涉及.
__attribute__
或者__declspec
)或编译器选项的内部共享,并且映像不是整个程序或从中转换的目标文件.翻译单元,因此没有标准概念可以准确地描述它.由于符号在C++中不是一个规范术语,它只是一个实现细节,即使方言的相关扩展可能已被广泛采用.命名空间范围const
变量的链接规则是特殊的(并且与const
在C语言中的文件范围中声明的对象特别不同,其也具有标识符链接的概念).由于ODR是由C++强制实施的,因此除了inline
函数之外,在整个程序中保持不超过一个相同变量或函数的定义是很重要的.如果没有这样的特殊规则const
,最简单的const
变量声明= xxx
包含多个翻译单元包含的标题或源文件(通常是"标题文件")中的初始值设定项(例如)(或者一个翻译单元不止一次包含,虽然很少)在程序中会违反ODR,这使得使用const
变量替换某些类似对象的宏是不可能的.
我认为C++中的内部和外部链接给出了一个清晰简洁的解释:
翻译单元是指实现(.c/.cpp)文件及其包含的所有标题(.h/.hpp)文件.如果此类翻译单元内的对象或函数具有内部链接,则该特定符号仅对该翻译单元内的链接器可见.如果对象或函数具有外部链接,则链接器在处理其他转换单元时也可以看到它.static关键字在全局命名空间中使用时,会强制符号具有内部链接.extern关键字导致符号具有外部链接.
编译器默认符号链接,以便:
非const全局变量默认具有外部链接
Const 默认情况下,全局变量具有内部链接
函数默认情况下具有外部链接
基本上
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++/
归档时间: |
|
查看次数: |
124520 次 |
最近记录: |