C++中extern的作用

1.2k 词

参考:
https://csguide.cn/

一般而言,C++全局变量的作用范围仅限于当前文件,但同时C++也支持分离式编译,允许将程序分割为若干个文件被独立编译。

在文件间共享变量数据,这里extern就发挥了作用。

extern用于指示变量或函数的定义在另一个源文件中,并且当前源文件中声明。说明该符号具有外部链接属性。

编译器将不会对extern指示的符号定义,链接器回去寻找。

符号的声明与定义

C/C++中变量的声明和定义时两个不同的概念。声明是指告诉编译器某个符号存在,在程序变量表中记录类型和名字,而定义则是指为该符号分配内存空间或实现其代码逻辑。

凡是没有待extern的声明同时也都是定义。而对函数而言,带有{}是定义,否则是声明。如果想声明一个变量而非定义它,就在变量名前添加关键字extern,且不要显式的初始化变量。

链接属性

在C++中,链接属性是指程序在编译、链接和执行阶段如何处理符号的可见性和重复定义。

外部链接

外部链接的符号可以在不同的源文件之间共享,并且在整个程序执行期间可见。全局变量和函数都具有外部链接。

内部链接

内部链接的符号只能在当前源文件内部使用,不能被其他源文件访问。用static修饰的全局变量和函数具有内部链接。

无链接

无链接的符号只能在当前代码块内部使用,不能被其他函数或代码块访问。

const constexpr修饰的常量具有无链接属性(一般情况下,编译器不会为const对象分配内存,也就无法链接)。

外部C链接

外部C链接的符号与外部链接类似,可以在不同的源文件间共享,并且在整个程序执行期间可见。

它们具有C语言的名称和调用约定,可以与C语言编写的代码进行交互。

在C++中,可以用extern "C"关键字来指定外部C链接,从而使用一些C的静态库。

extern作用

声明变量但不定义

声明变量或函数的存在,但不进行定义,让编译器在链接时在其他源文件中查找定义。

这使得不同的源文件可以共享相同的变量或函数。

当链接器在一个全局变量声明前看到extern关键字,链接器会尝试在其他文件中寻找这个变量的定义。

这里强调全局且非常量的原因是,全局非常量的变量默认是外部链接的。

常量全局变量的外部链接

全局常量默认是内部链接的,所以想要在文件间传递全局常量需要在定义时指名extern.

1
2
3
4
5
// a.cpp
extern const int NUM = 10; // 定义

// b.cpp
extern const int NUM; // 声明

编译和链接过程

编译链接时:

  1. 在编译时,extern用于告诉编译器某个变量或函数定义在其他源文件中,编译器会为它生成一个符号表项,并在当前源文件中建立一个对该符号的引用。
  2. 在链接时,链接器将多个目标文件合并成一个可执行文件,并且在当前源文件中声明的符号,会在其他源文件中找到对应的定义,并将它们链接起来。
留言