如何在C99多文件项目中声明内联函数?

我想在项目中定义一个内联函数,用c99编译。 我该怎么做? 当我在头文件中声明该函数并在.c文件中提供详细信息时,其他文件无法识别该定义。 当我将显式函数放在头文件中时,我遇到了问题,因为使用它的所有.o文件都有定义的副本,因此链接器给出了“多重定义”错误。

我想要做的是:

header.h inline void func() { do things... } lib1.c #include "header.h" ... lib2.c #include "header.h" 

使用lib1.o和lib2.o的实用程序

不幸的是,并非所有编译器都完全遵守C99,即使他们声称他们是。

一种符合要求的方法是

 // header file. an inline declaration alone is // not supposed to generate an external symbol inline void toto(void) { // do something } // in one .c file, force the creation of an // external symbol extern inline void toto(void); 

例如,较新版本的gcc可以正常工作。

你可以通过定义类似的东西来为其他编译器(伪装者)侥幸逃脱

 #ifdef PRETENDER # define inlDec static # define inlIns static #else # define inlDec # define inlIns extern #endif // header file. an inline declaration alone is // not supposed to generate an external symbol inlDec inline void toto(void) { // do something } // in one .c file, force the creation of an // external symbol inlIns inline void toto(void); 

编辑:

我所知道的支持C99的编译器(通常是选项-std=c99

  • gcc(版本> = 4.3 IIRC)实现了正确的inline模型
  • pcc也是对的
  • ggc <4.3需要一个特殊的选项来实现正确的模型,否则他们会使用自己的模型,如果你不小心,会产生多个定义的符号
  • 如果您不特别小心,icc只会在每个单元中发出符号。 但这些符号是“弱”符号,因此它们不会产生冲突。 他们只是炸毁你的代码。
  • opencc,AFAIR,遵循旧的gcc特定模型
  • clang根本不为inline函数发出符号,除非你有一个extern声明并且你在一个编译单元中使用函数指针。
  • tcc只是忽略了inline关键字

如果单独使用,则在C99 inline要求函数在与使用它相同的转换单元中定义(因此,如果在lib1.c中使用它,则必须在lib1.c中定义)。

您还可以将方法声明为static inline (并将定义放在两个源文件之间共享的头文件中)。 这避免了多重定义问题,并允许编译器在所有使用它的翻译单元中内联文件(如果您只是在一个翻译单元中声明该function,它可能会或可能不会这样做)。

见: http : //www.greenend.org.uk/rjk/2003/03/inline.html

我认为你在Header文件中定义和声明函数时不需要使用内联字,编译器通常默认将它作为内联,除非它太长,在这种情况下它会足够聪明地对待它作为正常function。

我认为多重定义可能是由Header文件中缺少Include Guard引起的。

你应该在标题中使用这样的东西:

 #ifndef HEADERNAME_H #define HEADERNAME_H void func() { // do things... } #endif