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

mou*_*mer 25 c linker c99 inline-functions

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

我想要做的是:

header.h
inline void func()
{
    do things...
}


lib1.c
#include "header.h"
...

lib2.c
#include "header.h"
Run Code Online (Sandbox Code Playgroud)

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

Jen*_*edt 26

不幸的是,并非所有编译器在这一点上完全符合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);
Run Code Online (Sandbox Code Playgroud)

较新版本的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);
Run Code Online (Sandbox Code Playgroud)

编辑:

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

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


Jon*_*onW 5

如果inline单独使用,则在 C99 中要求该函数在使用时在同一翻译单元中定义(因此,如果在 lib1.c 中使用它,则必须在 lib1.c 中定义)。

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

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