In my question I originally asked these four questions
- In C99 compilers, is the behavior of
inline
implementation defined when it comes to inlining across translation units? - If so, should it be avoided?
- Is there some other generally accepted way of doing this?
- If my
inline
function doesn't get inlined everywhere, would I at least get some sort of linker error?
After my OP I discovered that the first question has been discussed at length already in the following threads:
- How to declare an
inline
function in C99 multi-file project? - Is
inline
withoutstatic
orextern
ever useful in C99?
There are more threads on this topic, but these two seemed to hit the nail on the head.
So, based on these two discussions we can see that the answer to question 1 is YES. Compilers definitely have some freedom W.R.T. how they handle the inline
specifier.
We also see that for this to work inline
functions must be defined in a header.
Then beyond that the following options exist:
- The function definition in the header may have a
static
specifier. - If the header definition does not have a
static
specifier, it may be declared viaextern
in some common header file that all C files calling the function will also#include
. - If methods 2 and 3 are not used, method 4 would be to declare this
inline
function viaextern
in every C file that wishes to call it.
So, now that all of that explanation is out of the way, I would like to refocus this question on my original items #2 and #3 – should I even be doing this, and if so what's the most acceptable way?
Should I be doing this - or should this be avoided as much as possible?
Consider my application – I have a one line function in a driver that is called frequently (≈ several hundred times a second), but only from 3 or 4 other places. So using inline
will not contribute to code bloat – in fact the result will be negligible. Gregory Pakosz outlines when to use an inline
function and when not to nicely in this answer. So therefore, the answer would be very clear if this were one function being used in one translation unit. But that's not what I am asking.
In this situation I do not need to inline this function. But should I? I will probably never notice any performance difference because I inlined just this one function. But I am trying to figure out if I should make this my general practice in all similar situations. If I inline short functions that are frequently called more aggressively I may see a performance improvement. (My runtime environment is a low power 16bit RISC MCU – that's probably an important detail.)
The reason for asking is this is because there seems to be a disagreement among programmers about this. Is it bad etiquette for some reason to inline functions across translation units (no matter how you do it), and if so, why?
Assuming I do inline functions across translation units, what's the least detestable or most acceptable way?
Putting static
in a header seems to work well and may be the most portable way to do it. This was pointed out by pts in the comments and by and buzz in the answers. On the surface it seems like I am using static
to facilitate using something globally – which is nuts! But I suppose I can more correctly think about it like this: every function that inlines this function will have its own static copy as if it were defined in each of the respective C files as static inline
. If that understanding is correct then it seems like the behavior would always be predictable – the linker would have to give me notice if there are two functions with the same name in a translation unit.
I am not sure how I feel about declaring a functions via extern
in a header. The wording in 6.7.4 is that external definition in another translation unit is “not forbidden”.