In C++, the keyword "inline" serves two purposes. First, it allows a definition to appear in multiple translation units. Second, it's a hint to the compiler that a function should be inlined in the compiled code.
My question: in code generated by GCC and Clang/LLVM, does the keyword "inline" have any bearing on whether a function is inlined? If yes, in what situations? Or is the hint completely ignored? Note this is a not a language question, it is a compiler-specific question.
[Caveat: not a C++/GCC guru] You'll want to read up on inline here.
Also, this, for GCC/C99.
The extent to which
suggestions made by using the inline
function specifier are effective (C99
6.7.4).
- GCC will not inline any functions if the -fno-inline option is
used or if -O0 is used. Otherwise, GCC
may still be unable to inline a
function for many reasons; the
-Winline option may be used to determine if a function has not been
inlined and why not.
So it appears that unless your compiler settings (like -fno-inline
or -O0
) are used, the compiler takes the hint. I can't comment on Clang/LLVM (or GCC really).'
I recommend using -Winline
if this isn't a code-golf question and you need to know what's going on.
An interesting explanation from gcc: An Inline Function is As Fast As a Macro:
Some calls cannot be integrated for
various reasons (in particular, calls
that precede the function's definition
cannot be integrated, and neither can
recursive calls within the
definition). If there is a
nonintegrated call, then the function
is compiled to assembler code as
usual. The function must also be
compiled as usual if the program
refers to its address, because that
can't be inlined.
Note that certain usages in a function
definition can make it unsuitable for
inline substitution. Among these
usages are: use of varargs, use of
alloca, use of variable sized data
types (see Variable Length), use of
computed goto (see Labels as Values),
use of nonlocal goto, and nested
functions (see Nested Functions).
Using -Winline will warn when a
function marked inline could not be
substituted, and will give the reason
for the failure.
As required by ISO C++, GCC considers
member functions defined within the
body of a class to be marked inline
even if they are not explicitly
declared with the inline keyword. You
can override this with
-fno-default-inline; see Options Controlling C++ Dialect.
GCC does not inline any functions when
not optimizing unless you specify the
`always_inline' attribute for the
function, like this:
/* Prototype. */
inline void foo (const char) __attribute__((always_inline)); The remainder of this section is specific
to GNU C90 inlining.
When an inline function is not static,
then the compiler must assume that
there may be calls from other source
files; since a global symbol can be
defined only once in any program, the
function must not be defined in the
other source files, so the calls
therein cannot be integrated.
Therefore, a non-static inline
function is always compiled on its own
in the usual fashion.
If you specify both inline and extern
in the function definition, then the
definition is used only for inlining.
In no case is the function compiled on
its own, not even if you refer to its
address explicitly. Such an address
becomes an external reference, as if
you had only declared the function,
and had not defined it.
This combination of inline and extern
has almost the effect of a macro. The
way to use it is to put a function
definition in a header file with these
keywords, and put another copy of the
definition (lacking inline and extern)
in a library file. The definition in
the header file will cause most calls
to the function to be inlined. If any
uses of the function remain, they will
refer to the single copy in the
library.
How strong the hint is depends entirely on the compile options you use. Most compilers have options to do no inlining, only inline those marked 'inline', or use its best judgement and ignore the hints.
The last one probably works best. :-)