6.2.2 标识符的链接
TIP
“链接”回答的问题是:不同位置写出的同名标识符,是否指向同一个对象或函数。它和“作用域”不是一回事,二者经常一起出现,但解决的是不同问题。
在不同作用域中声明的标识符,或者在同一作用域中被多次声明的标识符,可以通过称为链接(linkage)的机制指代同一个对象或函数。链接有三种:外部链接、内部链接和无链接。20)
在构成整个程序的全部翻译单元与库的集合中,具有外部链接的某个特定标识符的每个声明,都表示同一个对象或函数。在单个翻译单元内部,具有内部链接的某个标识符的每个声明,都表示同一个对象或函数。无链接的每次声明,则都表示一个唯一实体。
如果某个文件作用域标识符的声明满足以下任一条件:
- 它是对象,并且声明中包含存储类说明符
static或constexpr; - 它是函数,并且声明中包含存储类说明符
static;
那么该标识符具有内部链接。21)
- 它是对象,并且声明中包含存储类说明符
对于使用存储类说明符
extern声明的标识符,如果在该作用域中先前已有一个对此标识符可见的声明,22)并且先前声明规定了内部链接或外部链接,那么后续声明中的该标识符具有与先前声明相同的链接。如果没有可见的先前声明,或者先前声明规定的是无链接,那么该标识符具有外部链接。若某个函数标识符的声明没有存储类说明符,则它的链接按“仿佛使用了
extern声明”来确定。若某个对象标识符的声明处于文件作用域,且不含static或constexpr存储类说明符,则它具有外部链接。下列标识符没有链接:
- 声明成“既不是对象也不是函数”的标识符;
- 声明为函数形参的标识符;
- 在块作用域内声明的对象标识符,并且其声明不带
extern存储类说明符。
如果在同一翻译单元中,同一个标识符同时以内部链接和外部链接出现,则行为未定义。
脚注说明
20)不同标识符之间不存在链接。
21)函数声明只有在文件作用域中才能包含 static 存储类说明符;见 6.7.2。
22)如 6.2.1 所述,后面的声明可能会隐藏前面的声明。