How to declare an inline function in C99 multi-file project?

谁都会走 提交于 2019-11-27 19:43:56

Unfortunately not all compilers are completely complying to C99 in that point even if they claim that they'd be.

An conforming way to do this is

// 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);

Newer versions of gcc, e.g, will work fine with that.

You may get away with it for other compilers (pretenders) by defining something like

#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);

Edit:

compilers with C99 support (usually option -std=c99) that I know of

  • gcc (versions >= 4.3 IIRC) implements the correct inline model
  • pcc is also correct
  • ggc < 4.3 needs a special option to implement the correct model, otherwise they use their own model that results in multiple defined symbols if you are not careful
  • icc just emits symbols in every unit if you don't take special care. But these symbols are "weak" symbols, so they don't generate a conflict. They just blow up your code.
  • opencc, AFAIR, follows the old gcc specific model
  • clang doesn't emit symbols for inline functions at all, unless you have an extern declaration and you use the function pointer in one compilation unit.
  • tcc just ignores the inline keyword

If used by itself, in C99 inline requires that the function be defined in the same translation unit as it's being used (so, if you use it in lib1.c, it must be defined in lib1.c).

You can also declare a method as static inline (and put the definition in a header file shared between two source files). This avoids the multiple-definition issue, and lets the compiler inline the file across all the translation units where it's used (which it may or may not be able to do if you just declare the function in one translation unit).

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

I think you don't need to use the inline word when you are defining and declaring the function inside the Header file, the compiler usually takes it as inline by default unless it's too long, in which case it will be smart enough to treat it as a normal function.

I think the multiple definition may be caused by the lack of a Include Guard in the Header file.

You should use something like this in the header:

#ifndef HEADERNAME_H
#define HEADERNAME_H

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

#endif
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!