3

In my question I originally asked these four questions

  1. In C99 compilers, is the behavior of inline implementation defined when it comes to inlining across translation units?
  2. If so, should it be avoided?
  3. Is there some other generally accepted way of doing this?
  4. 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:

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:

  1. The function definition in the header may have a static specifier.
  2. If the header definition does not have a static specifier, it may be declared via extern in some common header file that all C files calling the function will also #include.
  3. If methods 2 and 3 are not used, method 4 would be to declare this inline function via extern 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”.

Community
  • 1
  • 1
Nick
  • 1,361
  • 1
  • 14
  • 42
  • I don't understand why people willing to have [extern inline function](http://stackoverflow.com/questions/17504316/what-happens-with-a-extern-inline-function) – Bryan Chen Aug 20 '14 at 22:07
  • I am not talking about putting the extern in the H file necessarily. – Nick Aug 20 '14 at 22:10
  • 1
    so what are you talking about? show some code please. and if you want inline function, you much put code in header file. (unless you are using link-time optimization, which you don't need `inline` explicitly ) – Bryan Chen Aug 20 '14 at 22:11
  • 1
    Yes, I am talking about putting the function BODY in the header. But not the keyword EXTERN. The extern declaration would happen in each C file that needs to access this inline function remotely. – Nick Aug 20 '14 at 22:12
  • 1
    code and example please. I still don't understand your question. – Bryan Chen Aug 20 '14 at 22:15
  • You can't have an inline in a library. If you are trying to make it apart of an API then you must include the inline function in a .h file (no extern). – Clarus Aug 20 '14 at 22:48
  • @Claris I understand that part - And I did provide the function in the H file (but I am not sure how I feel about it!). But I still MUST use an extern declaration in every C file that calls this (or put an extern in some H file that gets included by every C file that calls this) or I can't build it - I get linker errors. I am not using GCC - I am using IAR Embedded workbench for MSP430. Anyway, this builds, everything is working fine. So my primary concern is *should* I be doing it this way? I would still like to have code that I can port to another C99 compiler if I ever need to. – Nick Aug 20 '14 at 22:53
  • 1
    This is very closely related to [Is `inline` without `static` or `extern` ever usefule in C99?](http://stackoverflow.com/questions/6312597/is-inline-without-static-or-extern-ever-useful-in-c99). – Jonathan Leffler Aug 20 '14 at 23:48
  • 1
    What's wrong with `static inline void foo(void) {}` in the `.h` file, and no more declarations anywhere else? – pts Aug 20 '14 at 23:53
  • @pts Hmm, I'll have to try that out tomorrow. On the surface it seems like it would go against the grain - when I see 'static' I think 'private' - but I guess that is a narrow view of what that specifier means. I am not sure I have ever declared/defined something static in a header before. – Nick Aug 21 '14 at 01:46
  • @JonathanLeffler Thanks for linking that other thread. I saw that too on the side bar after I asked the question originally. I have gone back and edited my post to differentiate it from the other threads and clear up my remaining questions about whether or not this is a practice in the first place. – Nick Aug 21 '14 at 20:29

1 Answers1

2

I think your driver.h should be like this:

static inline void foo(void)
{
    <one line>;
}

And your bar.c doesn't need extern inline void foo(void);, just call foo();, it'll work.

As for If my inline function doesn't get inlined everywhere like it should - would I at least get some sort of linker error warning me that a certain reference couldn't be found

You must use optimization option explicitly when you complie, Then you will have the inline function gets inlined actully. gcc bar.c -O2. And you can use objdump to check your code's assembly code, you'll find inline function gets inlined , instead calling foo, but get inlined there.

frank.lin
  • 1,614
  • 17
  • 26
  • This works method works - but so does extern. So which method is more correct and more portable? I've edited my question to focus more on the "should I be inlining functions across translation units" in the first place. – Nick Aug 21 '14 at 20:26
  • I think both are correct, as far as I know there is no difference, and choose the easy one.I'm a little confused about`should I be inlining functions across translation units`.1 What do you mean by `across translation units`? you mean to across platform or just across moduls and libraries.2 You should inline function which should be inlined, those that are small and have no loop in it. – frank.lin Aug 22 '14 at 02:32
  • I mean: is it bad etiquette to use inline functions across modules. I understand it is perfectly valid per the C99 standard - but is it generally discouraged by programmers and if it is, what's the reasoning? Does it really make things more difficult to debug, does it make the code harder to follow, does it somehow decrease readability? I only ask because I've seen message board discussions where it was discouraged but no explanation was given. – Nick Aug 22 '14 at 14:12
  • 1
    @Nick even though this is hopefully old. consider the following: if you inline across translation units. is that bad? not per se. if you are selling a binary blob to somebody else and give him a header file (read cross module inlining). if you change that inline function, your customers are forced to recompile. might be pretty bad. – Alexander Oh Feb 18 '15 at 21:02
  • 1
    @Alex This is a very late response to your very late comment - very nice point. – Nick Mar 15 '17 at 20:03