Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 312
mousomer Avatar asked Mar 08 '11 06:03

mousomer


People also ask

How do you declare a function inline?

An equivalent way to declare an inline member function is to either declare it in the class with the inline keyword (and define the function outside of its class) or to define it outside of the class declaration using the inline keyword.

What is __ inline in C?

The __inline keyword suggests to the compiler that it compiles a C or C++ function inline, if it is sensible to do so. The semantics of __inline are exactly the same as those of the inline keyword.

Does inline function use stack?

By definition, if the compiler has inlined a function, there is no explicit function call at the calling site because the compiler has replaced the call with the body of the function. Thus, there will be no stack setup for the call.


2 Answers

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
like image 158
Jens Gustedt Avatar answered Oct 08 '22 02:10

Jens Gustedt


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

like image 41
JonathonW Avatar answered Oct 08 '22 02:10

JonathonW