Search code examples
cinlinec-header

Is it wrong to place inline functions in C headers?


I am building a C project for several compilers, some of which are legacy compilers which don't seem to have link time inlining support, so it seemed logical to place static inline functions directly in headers and actually have each translation unit have its own copy.

Also, I need to ensure certain functions are inlined so that there are no calls to other functions (i.e. changes to CPU registers) when called inside certain low-level interrupt handlers, so it's not simply about letting the compiler choose if it will affect performance.

However, a colleague of mine told me this is an unusual thing to do and I should avoid it. At this point in project I can probably still rearrange everything, so I would just like to confirm if there are some issues we might face in the long run if we decide to use header inlines?


Solution

  • From n1570 (latest public C11 draft), §6.7.4:

    1. A function declared with an inline function specifier is an inline function. Making a function an inline function suggests that calls to the function be as fast as possible. The extent to which such suggestions are effective is implementation-defined.

    The next section goes into details about linkage, but this passage above is basically all the C standard has to say about inline. Note how this gives the implementation every freedom, including to completely ignore inline.

    Therefore, with just standard C, you could end up with multiple instances (one per translation unit) of a function that is called in the normal way. This is normally not what you want, as it combines two disadvantages (duplicated code and the overhead of a function call). So I'd argue the standard C inline is only ever useful for functions private to a single translation unit. Even then, you could assume a good optimizing compiler will automatically pick candidates for inlining, without an explicit inline.

    If on the other hand your compiler provides a way to actually force inlining of a function (which according to your comments, the _inline specifier does for your compiler), having these functions in a header is safe. But be aware it is in no way portable.

    As commented by cmaster, you can achieve kind of "manual inlining" with function-like macros instead for a portable solution.