12 Apr 2003 raph   » (Master)

Inline functions in C

I was looking again at the question of how to do inline functions in C. There's a relatively recent page by one Richard Kettlewell, but it doesn't quite explain how to do inline functions really portably, in particular so that code will work correctly on compilers which don't support inline functions.

I think this goal is achievable without too much pain. Here's a sketch.

1. Guess conservatively whether the compiler has a keyword for inline, and define it to be "inline". Here's a sketch:

#if defined(__GNUC__)
#define inline __inline__
#elif defined(_MSC_VER)
#define inline __inline
#elif !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
#define DISABLE_INLINING
#define inline
#endif

An enhancement of this code would be to detect the cases where autoconf is able to detect the compiler's support for inline and report it in a "config.h" file or the like. See, though this mail for a cautionary note.

2. Set up a DEF_INLINE macro. This macro makes an inline definition when available, otherwise a standard function declaration:

#ifdef DISABLE_INLINING
#define DEF_INLINE_BODY(proto, body) proto { body }
#define DEF_INLINE(proto, body) proto;
#else
#define DEF_INLINE_BODY(proto, body) static inline proto { body }
#define DEF_INLINE DEF_INLINE_BODY
#endif

3. Then, in your .h files, define your inline functions as follows:

DEF_INLINE( void unref(obj *o),
    if (--o->refcnt == 0) destroy(o);
)

4. Now for the slightly tricky part. In one .c file, include the following fragment:

#undef DEF_INLINE
#define DEF_INLINE DEF_INLINE_BODY
#include "yourfile.h"

A possible enhancement is to set DEF_INLINE back to its old value, but if yourfile.h is the last included file, it's just more code.

This approach has the advantage that you can disable inlining with a simple switch. This might be handy for debugging (for example, setting breakpoints in the inlined function), and also to measure the performance improvement actually achieved.

The drawback, of course, is the use of the C preprocessor. It's too easy to try to create your own language using C macros, and often a bad idea.

If you only care about GCC, MSVC, and C99 compliant compilers, you can get by with just step 1. In fact, it'll probably still work on older compilers, but with the downside of replicating the "inlined" functions in every .c file that includes them.

It's a shame that such a simple and valuable feature is such a mess when it comes to standards and actual implementations. Ah well.

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!