4

Here inline is used in both definition and declaration which compiles successfully:

#include <stdio.h> inline int add(int a , int b); inline int add(int a , int b){ return a+b; } int main(){ printf("%d\n", add(1,2)); return 0; } 

It also compiles fine if we use inline in either definition OR declaration.

Which one is the correct way of doing it? is there a rule in C to explain it as there are similar rules for static and extern?

4
  • Not fully, still want to know why other methods are compiling and running. Commented Jun 15, 2020 at 13:28
  • @Josh: why wouldn't they compile? A non-static inline function will still be visible to other compilation units (if they choose to include the declaration) and usually won't be inlined in other units, unless compiler is configured to do link-time optimizations. If you want an inline function which has to be inlined in many compilation units, make it static inline and place it into a header file. Commented Jun 15, 2020 at 13:48
  • Usually, a declaration is not needed (i.e. a definition will suffice). Commented Jun 15, 2020 at 13:50
  • Take a look at this on how static keyword is used: stackoverflow.com/questions/62379166/…. I'm looking for the same kind of rules in C for inline. Commented Jun 15, 2020 at 13:51

2 Answers 2

2

even the inline needs a body. So if you only

inline int add(int a , int b); 

you just inform the compiler that there is a function called add taking two ints as the parameters and returning int. You give the compiler a hint that you would like this function to be inlined.

but what will actually happen depends on the implementation.

gcc will only link the program successfully if optimizations are enabled. If not compiler will not emit the not inlined version of the function and the linking will fail. https://godbolt.org/z/yQj3jC

To make sure that it will link in any circumstances you need to:

int add(int a , int b); inline int add(int a , int b){ return a+b; } 

In this case yuo will have not inlined version of the function but compiler will inline it if it finds it necessary https://godbolt.org/z/2BDA7J

In this trivial example function will be inlined when optimizations are enabled even if there is no inline keyword. https://godbolt.org/z/h3WALP

inline is just the hint and compiler may choose to inline it or not. Some compilers have special mechanisms to force inlining

inline __attribute__((always_inline)) int add(int a , int b){ return a+b; } 
Sign up to request clarification or add additional context in comments.

6 Comments

Interesting, I thought if declaration is inline, then compiler automatically will assume any implementation is also should be inlined.
It gets trickier when multiple translation units are involved. 6.7.4 p10 says "An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit."
@IanAbbott Yes but it far beyond the level of the question. There was a copy-paste mistake as well.
@P__J__ Yes, it is easy to get confused. Indeed, I was confused by "An inline definition" because that only exists when there is no external declaration of the function in file scope. So an inline function definition will also be the externally linked definition of the function if it has an external declaration at file scope. In that case, the inline may still act as a hint to the compiler, and the function still has certain restrictions.
So the correct way is to always add the keyword at the definition and not the declaration?
|
1

Different combinations of extern and inline and no function specifiers may be valid and will compile, yet the behaviour may be different.

Whether a function will actually be inlined is defined by these two paragraphs of the C99-standard (cf, for example, this online C99 standard draft):

6.7.4 Function specifiers

...

(6) 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.138) The extent to which such suggestions are effective is implementation-defined.139)

(7) Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.140)

Paragraph (6) defines that - even if a function is an "inline function" - it is implementation defined whether it is actually "inlined" or not.

Paragraph (7) says that only if all the declarations of a file-scope function identifier are marked as inline and none of them is marked as external, then the function is defined inline.

In your example, since you do not use an external keyword, the function will be defined as inline. If it is actually inlined is, according to paragraph (6), still implementation defined.

1 Comment

Interestingly, GCC does not seem to require an explicit extern keyword to turn an inline defined function into an externally linked one. So adding int add(int, int); to the code behaves the same as adding extern int add(int, int); to the code. In either case, GCC produces an externally linked add function (that can be called from other translation units). I wonder if that's a bug in GCC.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.