在C++中链接是什么?
C++的链接和链接器的链接有所不同。
在讲C++中链接是什么之前先了解一下标签、实体与名字
标签、实体与名字
名字
一个名字是一个标识符、运算符函数标识、转换函数标识或模板标识的符号。
标签
标记语句中的标签由goto语句和标签表达式引入。如下所示。
标记语句中的标签只能作为goto的目标。
1 | A: // 引入标签A |
switch语句中的case标签和default标签,它们仅能出现在switch语句中。
1 | switch(N) { |
标记语句中会引入一个标签,同时还有代表这个标签的名字,要不然怎么goto到这个标签呢?不过switch中的case标签和default标签并没有名字。
实体
一个实体是一个值、对象、引用、结构化绑定、函数、枚举器、类型、类成员、位域、模板、模板特化、名字空间或包。
浅谈一下值和对象还有变量
值
值本质是一段由01构成的序列,可以存储一些信息。
在C++中,值仅在表达式中出现。例如,这个语句
1 int n = 1 + 2;在这里内置的加号
+
接收两个值,分别为1
和2
,然后在运算之后得到表达式1+2
的值3
然后赋值运算符
=
,将3
这个值赋值给n
。对象
对象拥有名字、存储期、生存期、类型
对象拥有它的值
变量
变量由声明引入,变量的名字表示一个引用或对象
实体由声明语句引入,由被算作定义的声明语句所定义。
链接
不考虑标签,只考虑名字与实体的关系。
一个名字按理说只在当前scope中有效。不过,
当一个名称可以表示与另一个scope内的声明引入的名称相同的对象、引用、函数、类型、模板、命名空间或值(绝大部分实体)时,就称其具有链接。
可以简单的认为scope就是一对花括号或者一个翻译单元
外部链接
名字可以跨翻译单元找到那个实体
模块链接
可以跨模块找到那个实体
内部链接
可以在当前翻译单元找到那个实体
无链接
仅在当前scope内找到那个实体
总的来说,有链接就是可以跨scope使用名字,没有则不行。
值得注意的一些问题 :
没有extern修饰的全局变量拥有内部链接,而函数拥有外部链接
无论是否有链接,都可以在子scope中被找到
要注意大多数时候名字需要被提前声明或定义。
有的实体在多个scope中被多次定义,可是有时却指向相同实体,例如类、有inline
修饰符的全局变量或静态成员变量等。
语言链接
有的时候,我们需要跨语言使用一个函数,这时候就需要语言链接
注意语言链接仅会作用于函数
1 | extern string-literal declaration |
例如
1 | extern "C++" int add(int, int); |
C++标准只定义了"C"
和"C++"
的语言链接,其余的语言链接由实现定义。