Will compilers inline functions without bodies?

Let's imagine a blah.h header file that contains:

// A declaration without any code. We force inline
__attribute__((always_inline)) void inline_func();

And a blah.cpp source file that contains:

#include "blah.h"

// The code of the inline function
void inline_func() {
    ...
}

// Use the inline function
void foo() {
    inline_func();
}

The question is, will the compiler actually inline the inline_func()? Should the code be with the declaration or they can be separate?

Upvotes: 1

Views: 637

Answers (3)

Paolo M
Paolo M

Reputation: 12777

Well, it depends. In your example, it will be inlined, because the definition of the function is in the same translation unit where it is used.

Otherwise, if no LTO is possible, and at compile time the definition of the function is not available to the compiler, then no, the function will not be inlined.


Prior answer

The answer is: it depends. It depends on the compiler, and it may depend on compiler's configuration(1)(2) too.

See also inline description at cppreference.com (quoted below):

The intent of the inline keyword is to serve as an indicator to the optimizer that inline substitution of the function is preferred over function call, that is, instead of executing the call CPU instruction to transfer control to the function body, a copy of the function body is executed without generating the call. This avoids extra overhead created by the function call (copying the arguments and retrieving the result) but it may result in a larger executable as the code for the function has to be repeated multiple times. Since this meaning of the keyword inline is non-binding, compilers are free to use inline substitution for any function that's not marked inline, and are free to generate function calls to any function marked inline. Those choices do not change the rules regarding multiple definitions and shared statics listed above.

Upvotes: 1

MSalters
MSalters

Reputation: 180303

Inlining is a two-step process: * Is it possible? * Is it worthwhile?

The first step is fairly trivially decided by the compiler, the second is a far more complex heuristic. Thus it makes sense to only consider the benefits of possible optimizations.

always_inline means that the second step is ignored. It does not affect the first consideration. Now, you've also stated that LTO is disabled, which means that first consideration, the ability for inlining, is restricted. This shows that LTO and always_inline are pretty unrelated since they affect two different inlining considerations.

Not that LTO matters for your example anyway. The two functions under consideration are in the same Translation Unit. There appear to be no other restrictions such as recursion, library calls, or other observable side effects. That means it should be possible to inline, and since that's the only consideration, it should be inlined.

Upvotes: 2

ted
ted

Reputation: 4985

You need to have the body available at the time the inlining is supposed to happen.

I.e. if you have the following files:

inlineFunc.h
inlineFunc.c
main.c

And you compile with:

compile inline.c
compile main.c
link innline.o mcompile inline.c

compile main.c link innline.o main.o yourCoookProgramain.o yourCoookProgram

there is no way that inlineFunc gets inlined in main.c however calls to inlineFunc in inlineFunc.c can be inlined.

As Paolo mentioned, inline is only a hint to a compiler however some compilers also have ways to force the inining, i.e. for gcc you can use __attribute__(always_inline). Take alook here for a discussion on how gcc handles inlining.

An interesting sitenote:

The warning is issued in this case as the definition of foo() is not available when main() is compiled. However, with -O2 or better optimizations, gcc performs a kind of "backward inlining", meaning that even function definitions that are further ahead in the source file can be embedded into a caller. Consequently, the warning disappears as soon as one uses at least -O2 optimizations. Is there any specific option responsible for this behavior? I would like to enable "backward inlining" even with -O1 or -O0.

Upvotes: 1

Related Questions