Search code examples
clinkerc99inline-functions

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


I want to define an inline function in a project, compiled with c99. How can I do it? When I declare the function in a header file and give the detail in a .c file, the definition isn't recognized by other files. When I put the explicit function in a header file, I have a problem because all .o files who use it have a copy of the definition, so the linker gives me a "multiple definition" error.

What I am trying to do is something like:

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


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

lib2.c
#include "header.h"

with a utility which uses both lib1.o and lib2.o


Solution

  • 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 definition 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