-1

I always though that the compiler can choose between inserting the function as is or to treat it as a regular function.

However I don't think it is possible if the inline function is defined in the header file (and can be included from multiple source files).

Is this correct?

Thanks

user207421
  • 305,947
  • 44
  • 307
  • 483
user2102697
  • 29
  • 1
  • 8
  • 2
    [This old answer](http://stackoverflow.com/a/7767858/440558) should hopefully help you understand. – Some programmer dude May 10 '16 at 06:42
  • I think it will cause linkage problem (multiple definitions of the same symbol) if it is included from multiple source files. Have you tried it? – barak manos May 10 '16 at 06:43
  • [This question](http://stackoverflow.com/questions/6312597/is-inline-without-static-or-extern-ever-useful-in-c99) is also very useful. Bear in mind that the behaviour is different between ISO C, GNU C, and C++. – M.M May 10 '16 at 06:48
  • Your question has nothing to do with [tag:real-time]. Don't tag indiscriminately. – user207421 Oct 30 '16 at 00:31

3 Answers3

1

Yes, the compiler is completely free to chose if he really inlines an inline function. Actually he is free to inline any function, for which he has seen a definition.

inline as a keyword was introduced to avoid the "multiple symbol definition" problem. As such, it only makes sense if you have the definition in a header file.

The usual scheme is to have a definition like

inline void toto(void) {
  ...
}

in a header file that is included by several TU. Then in exactly one TU you have a declaration without inline

void toto(void);

which ensures that the symbol is exported by this TU.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • _inline as a keyword was introduced to avoid the "multiple symbol definition" problem_....?? Are you sure... – LPs May 10 '16 at 06:53
  • 1
    @LPs, yes, what other reason would there be? The compiler can inline any function that has a definition. `inline` ensures that more such definitions can be made visible to all TU of a project. – Jens Gustedt May 10 '16 at 06:56
  • So just to make sure, you are saying it can take the inline, change it to not inline so it can be used from multiple sources? – user2102697 May 10 '16 at 07:10
  • @user2102697, I am not sure that I understand what you are asking. – Jens Gustedt May 10 '16 at 09:55
  • I'm pretty sure that the inline keyword was introduced (by C++) for the purpose of inlining functions, as a way of manual, "pre-mature" optimization. Keep in mind that this keyword was invented long before C99, at a time when compilers were crap at optimizing code. – Lundin May 10 '16 at 11:42
  • I ever thought `inline` keyword was introduced to suggest to compiler to inline functions, not to suppress warnings/errors and I was asking if you have a reference about what you wrote. @Lundin I think clarify all things. – LPs May 10 '16 at 15:26
1

In ISO C99 and ISO C11, having in the header file:

inline void f(void) { ..... }

means that the compiler can indeed choose between inlining the function, or treating it as a regular function.

However, when treating as a regular function, the compiler will behave similarly to if you had written void f(void);, i.e. it will expect to link to a body of f elsewhere.

So you need to put in exactly one of your translation units the line:

extern inline void f(void);

which causes the compiler to emit the body in that unit.


However, in GNU C, using inline void f(void) { ... } leads to undefined behaviour. The compiler can still choose, but when it chooses to treat as a regular function, it behaves as if you had written void f(void) { ... }, i.e. it emits the function body in every translation unit that uses it.

Some people write their functions in the header as static inline void f(void) { .... }, which works in both ISO C and GNU C, but possibly makes it harder for the linker to combine all of the copies into one.

See this thread for more detail

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
0

Assuming that an inline function is defined in a header like: inline void f(void) { ... } ...I can see two questions in your message, indeed:

  1. Do you have to include that header with function definition in every translation unit (TU) in which you are going to use this function?
  2. Is the compiler free to inline the function in some TUs, while not inlining it in other TUs, within the same project?

Ad.1: Short answer: Yes.
Long answer:
For compilation, definition (not only declaration!) of an inline function must be visible in every TU, where you are going to call it. Including the header in every TU is the best solution here.
By omitting the function’s storage class specifier in the header (as in the above code snippet, which is OK here, see below for short discussion on using extern or static), you go with the default, which means for inline functions: inline keyword is active in each TU in which you include this header. The function retains default external linkage (!), so it is also accessible from other TUs (i.e. in TUs not including this header), but the keyword inline is not active in the TUs that do not include functions’ inlined definition.
Now the linker must put a version of the function in some of the object files, so the function can be linked from the object files generated from TUs which do not include this functions’ ‘inline’ definition (or to the TUs where compiler decided not to inline despite the inline keyword).
You indicate that single TU by re-declaring the function as non-inlined, by adding after the included header file: void f(void); If you add static before your inline function definition in header, then each TU will generate its own copy and your executable code will probably take more space (subject to the zillion factors influencing code size with inlining). But you do not need to re-declare the function in any TU as non-inlined.
If you add extern to your inline function definition in header, then you will get ‘undefined reference’ linker error as none of TUs will generate executable code for it, despite possessing function’s definition (=knowing its body). To avoid it, at least one TU must additionally contain non-static re-declaration of this function: inline void f(void); (Note that GCC implements three different inlining semantics in C programs (GNU C90, gnu_inline, and one used e.g. with -std=c99), but to my knowledge none of them conforms to the above.)

Ad2: Yes. Even within a single TU the compiler is free to inline only a subset of calls to the inline function, or inline all calls, or none. Being honest, the same applies to functions defined without the inline keyword, because most compilers will try to ‘inline’, as part of their optimizations, even when the keyword is not used. After all, the keyword is just a hint to the compiler, as others have already highlighted in their comments/responses.

Artur Opalinski
  • 1,052
  • 7
  • 12