前几天,一个同事跟我说在我们的代码库里面看到,一个static函数被放在了头文件里面,可构建的时候却没有报告链接错误。我的第一反应也是,函数被放在头文件里面,当这个头文件被多个源文件引用之后,再把那几个源文件编译产生的目标文件链接起来的时候,应该会产生重定义错误的……
后来又仔细一想,static关键字不正是解决不同的源文件中、同名函数的命名冲突问题的吗?于是,快速做了一个小验证:
//“static_func.h”
#include <stdio.h>
static void display() {
printf("This is static function in a header file.\n");
}
//“funcA.c”
#include "static_func.h"
void funcA() {
printf("This is funcA...\n");
display();
}
//“funcB.c”
#include "static_func.h"
void funcB() {
printf("This is funcB...\n");
display();
}
//“main.c”
extern void funcA();
extern void funcB();
int main()
{
funcA();
funcB();
return 0;
}
正常编译、链接没有问题,可执行文件也能正常执行,证明了存在同名static函数的不同源文件链接到一起是没有问题的。
虽然还不清楚编译器具体是怎么实现的,但是对于C语言的static函数可以简单的理解为,编译器在处理static函数时,可能把static函数所在文件的文件名当成了函数名的一部分,类似于C++中命名空间的概念。
使用‘nm’命令查看可执行文件,除了看到函数‘funcA’和‘funcB’之外,还看到了两个‘display()’,编译器最终是怎么区分这两个同名的函数的暂时还没有搞清楚,有待后续再进一步研究。