在使用C语言编写如下测试代码
1 2 3 4 5 6 7 8 9 10 11
| #ifndef __UTIL_H__ #define __UTIL_H__ #include <stdio.h> void logInfo(char* msg) { printf("%s\n", msg); } #endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <stdio.h> #include "util.h" int max(int a, int b){ if(a == b){ logInfo("无法比较大小,因为他们一样大"); return -10000; } if(a > b){ return a; } return b; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <stdio.h> #include "util.h" #include "a.c" int main() { int a = 0; int b = 0; logInfo("请输入两个数字:"); scanf("%d",&a); scanf("%d",&b); int maxNum = max(a, b); printf("最大的数:%d\n", maxNum); }
|
编译出现下面的结果
1 2 3 4 5 6 7
| [root@xxx abc]$ gcc main.c a.c util.h /tmp/ccNHb71g.o: In function `logInfo a.c:(.text+0x0): multiple definition of `logInfo /tmp/ccLwg1eA.o:main.c:(.text+0x0): first defined here /tmp/ccNHb71g.o: In function `max a.c:(.text+0x1a): multiple definition of `max /tmp/ccLwg1eA.o:main.c:(.text+0x1a): first defined here
|
分析之后发现原因为:
1、先有预处理程序把util.h分别包含进 main.c 和 a.c文件中。
2、由编译器和汇编器分别单独 编译+汇编 main.c a.c文件生成main.o 和a.o 到这里没有任何问题.
3、由连接器 ld 链接 main.o 和a.o 这里发现了重复定义的logInfo方法.
有几个规避该问题的方式
1、编译的时候直接 gcc main.c 这样就不会有a.c编译成a.o这一步骤。
2、将a.c改名为a.h,头文件是不会生成目标文件
总结
1 2 3 4 5 6
| #ifndef _INCLUDE_NTREG_H #define _INCLUDE_NTREG_H #endif
|
只能保证在一个源文件中不会重复多次引用。
你现在是在两个c文件中,而且这两个文件要链接成一个可执行文件,就会有两处定义。
最佳实践是头文件不能有变量的定义,可以有声明。