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

时间:2011-03-08 06:57:17

标签: 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"

使用同时使用lib1.o和lib2.o

的实用程序

3 个答案:

答案 0 :(得分: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);

新版本的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关键字

答案 1 :(得分:4)

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

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

请参阅:http://www.greenend.org.uk/rjk/2003/03/inline.html

答案 2 :(得分:-1)

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

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

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

#ifndef HEADERNAME_H
#define HEADERNAME_H

void func()
{
    // do things...
}

#endif