为什么头文件直接声明指针无法跨文件使用,加extern关键字才正常?
C语言多文件共享全局变量的编译差异原理
核心底层规则:声明与定义的区别
- 声明:仅向编译器告知变量的类型、名称,不会分配内存空间,同一个变量可以声明多次
- 定义:为变量分配实际的内存空间,同一个全局变量在整个可执行程序的所有编译单元中,有且只能有一个定义,否则链接阶段会报重定义错误
第一种写法编译失败的原因
头文件file1.h中的int* int_ptr;属于C语言中的暂定定义(Tentative Definition):在全局作用域下,没有初始化、也没有extern修饰的变量会被判定为暂定定义。
头文件会被每个包含它的.c文件完整展开,相当于file2.c和file3.c在预处理结束后,各自都有一个int* int_ptr;的暂定定义。链接阶段会将两个编译单元的符号合并,此时检测到两个同名全局变量的定义,直接触发重定义错误,和后续在.c中额外加的extern声明无关。
第二种写法编译正常的原因
头文件file1.h中的extern int* int_ptr;是纯变量声明,不会分配任何内存,无论多少个.c文件包含这个头文件,都只是告知编译器存在一个名为int_ptr的int型指针变量,内存分配不在当前编译单元。
只有file2.c中的int* int_ptr;是唯一的全局变量定义,负责分配内存。链接阶段所有文件对int_ptr的引用都会绑定到这个唯一的内存地址,不会产生冲突,因此编译链接正常。
补充说明
指针本质就是普通变量,和int、char等基础类型变量的多文件共享规则完全一致,没有特殊逻辑。全局变量跨文件共享的标准写法就是:
- 在公共头文件中加extern声明变量
- 在唯一的.c文件中定义变量(无extern修饰,可按需初始化)
- 其他需要用到该变量的.c文件直接引入公共头文件即可
内容的提问来源于stack exchange,提问作者user7216373
相关产品推荐
相关产品推荐

