我有以下三个文件:
#ifndef INLINE_HEADER_H
#define INLINE_HEADER_H
inline int func1() {
return 1;
}
#endif
Run Code Online (Sandbox Code Playgroud)
#include "inline_header.h"
Run Code Online (Sandbox Code Playgroud)
#include "inline_header.h"
int main() {
func1();
}
Run Code Online (Sandbox Code Playgroud)
当我编译只是source2.c用gcc source2.c它编译.但是,当我尝试编译时,gcc source1.c source2.c我得到一个多重定义错误,如下所示:
/tmp/cchsOaHF.o: In function `func1':
source2.c:(.text+0x0): multiple definition of `func1'
/tmp/ccEyUW0T.o:source1.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我正在使用Uccntu 14.04上的gcc 4.8.4进行编译.
我试过看了这个,发现了一个类似的问题,内联函数的多个定义.但是在他的情况下,错误是由他的内联函数的重新定义引起的.就我而言,我没有重新定义它(或者至少没有明确地......).
dbu*_*ush 15
将source1.c编译为source1.o时,它包含的定义func1.类似地,当您将source2.c编译为source2.o时,它还包含一个定义func1.因此,当您链接source1.o和source2.o时,会出现多重定义错误.
包含保护不会阻止这种情况的原因是因为source1.c和source2.c都是单独编译的.在单个编译单元中仅包含防护装置.
如果这不是内联函数,则在头文件中放置一个声明:
int func1();
Run Code Online (Sandbox Code Playgroud)
然后将定义放在一个源文件中.
但是,您将函数定义为inline.因此,您还需要声明它,static以便每个编译单元获得自己的函数副本.
如果您希望将此类函数放在标题中,它还必须是static:
static inline int func1() {
return 1;
}
Run Code Online (Sandbox Code Playgroud)
这将导致符号对于每个编译单元(文件)是本地的,从而避免任何链接器错误.
另外,从gcc 手册:
当内联函数不是静态的时,编译器必须假定可能存在来自其他源文件的调用; 由于全局符号只能在任何程序中定义一次,因此不能在其他源文件中定义该函数,因此无法集成其中的调用.因此,非静态内联函数总是以通常的方式自行编译.