16

I have been testing inline function calls in C++.

Thread model: win32
gcc version 4.3.3 (4.3.3-tdm-1 mingw32)

Stroustrup in The C++ Programming language wirtes:

The inline specifier is a hint to the compiler that it should attempt to generate code [...] inline rather than laying down the code for the function once and then calling through the usual function call mechanism.

However, I have found out that the generated code is simply not inline. There is a CALL instrction for the isquare function.

alt text

Why is this happening? How can I use inline functions then?

EDIT: The command line options used:

**** Build of configuration Debug for project InlineCpp ****

**** Internal Builder is used for build               ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc\InlineCpp.o ..\src\InlineCpp.cpp
g++ -oInlineCpp.exe src\InlineCpp.o
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
George
  • 15,241
  • 22
  • 66
  • 83
  • 1
    Have you checked what code gets generated when you up the optimization level? Also, try adding the `-finline-functions` parameter when compiling the code – Christoph Jun 01 '09 at 12:01
  • 2
    Please post the command line options you used with gcc to compile the code. (If you're not using one of -O3 or -finline-functions then gcc ignoring "inline" doesn't surprise me). – timday Jun 01 '09 at 12:25
  • 3
    the problem is the -O0 you hav ein your compiler flags, that means **no** optimizations. Switch that to -O2 and it'll be inlined just fine. – Evan Teran Jun 01 '09 at 15:12
  • 2
    Is -O2 really enough ? According to my info gcc (4.3.2), -finline-functions isn't enabled until -O3 (in fact it claims the only difference between -O2 and -O3 is -O3 adds -finline-functions and -frename-registers). And the docs for -O2 say "The compiler does not perform loop unrolling or function inlining when you specify `-O2'". – timday Jun 02 '09 at 20:34
  • @timday although the docs say otherwise I'm looking at a compilation annoyance (GCC causing an out of memory error) that disappears only when -fno-inline-functions is used. Observing the same pattern with -O2, -O3, -Os, I'm left under the impression that -O2 enables inlining. –  Jun 15 '12 at 09:59
  • @tea: gcc's inlining is pretty complicated, and gets more complicated with every version it seems. What actually gets inlined depends on optimisation level and/or explicit overrides e.g -finline-functions (-O3), -finline-small-functions (-O2), -finline-functions-called-once (-O1), -fearly-inlining (default) or the nuclear option of -finline-limit=N and a bunch of settable parameters. There's little substitute for inspection of the resulting assembler in understanding what the impact is (preferably in conjunction with a profiler to understand the cause of any resulting performance change). – timday Jun 15 '12 at 22:44

7 Answers7

48

Like Michael Kohne mentioned, the inline keyword is always a hint, and GCC in the case of your function decided not to inline it.

Since you are using Gcc you can force inline with the __attribute((always_inline)).

Example:

 /* Prototype.  */
 inline void foo (const char) __attribute__((always_inline));

Source:GCC inline docs

njsf
  • 2,729
  • 1
  • 21
  • 17
  • 5
    Yeah, but if the questioner goes away and starts pasting __attribute__((always_inline)); onto all his functions instead of just compiling with -O3, we've failed. – timday Jun 02 '09 at 20:46
  • 2
    Agreed. I guess I am still an optimist and believe most people have some common sense ;-) – njsf Jun 02 '09 at 22:29
  • For the record, I have to build with `-Os` and I need this because the compiler isn't inlining an object method that takes all constant arguments and is one line like `member = (big integer expression with no function calls and just integer math operations);`. gcc 4.6.1 BTW. – Mike DeSimone Jul 12 '12 at 00:55
  • 1
    For another record, I have to build with -Os (embedded system; won't fit otherwise) and the core scheduler of my RTOS is a big, nasty mess of inline assembly that loads some C variables. I absolutely must not make a function call as that would clobber some registers I need to save. With this attribute I've been able to break the core into something legible and export the assembly to self-documenting function calls. One use case for not pasting the attribute on all the functions! (also 4.6.1) – Kevin Vermeer Jul 16 '12 at 02:54
  • @KevinVermeer Your problem (to write a small inline function that doesn't obey the calling convention) would be solved in a more portable way by making a *macro* that expanded to GNU-syntax inline assembly. – Quuxplusone May 23 '14 at 19:14
23

There is no generic C++ way to FORCE the compiler to create inline functions. Note the word 'hint' in the text you quoted - the compiler is not obliged to listen to you.

If you really, absolutely have to make something be in-line, you'll need a compiler specific keyword, OR you'll need to use macros instead of functions.

EDIT: njsf gives the proper gcc keyword in his response.

Michael Kohne
  • 11,888
  • 3
  • 47
  • 79
8

Are you looking at a debug build (optimizations disabled)? Compilers usually disable inlining in "debug" builds because they make debugging harder.

In any case, the inline specified is indeed a hint. The compiler is not required to inline the function. There are a number of reasons why any compiler might decide to ignore an inline hint:

  • A compiler might be simple, and not support inlining
  • A compiler might use an internal algorithm to decide on what to inline and ignore the hints.
    (sometimes, the compiler can do a better job than you can possibly do at choosing what to inline, especially in complex architectures like IA64)
  • A compiler might use its own heuristics to decide that despite the hint, inlining will not improve performance
Euro Micelli
  • 33,285
  • 8
  • 51
  • 70
4

Inline is nothing more than a suggestion to the compiler that, if it's possible to inline this function then the compiler should consider doing so. Some functions it will inline automatically because they are so simple, and other functions that you suggest it inlines it won't because they are to complex.

Also, I noticed that you are doing a debug build. I don't actually know, but it's possible that the compiler disables inlining for debug builds because it makes things difficult for the debugger...

Graham
  • 4,095
  • 4
  • 29
  • 37
3

It is a hint and the complier can choice to ignore the hint. I think I read some where that GCC generally ignore it. I remeber hearing there was a flag but it still does not work in 100% of cases. (I have not found a link yet).

Flag: -finline-functions is turned on at -O3 optimisation level.

David Allan Finch
  • 1,414
  • 8
  • 20
  • 3
    I believe the main difference gcc pays to "inline" is that it means the function can be up to 600 instructions big and still get inlined, while functions not declared inline considered for auto inlining with -finline-functions have to be less than 300 instructions. You can mess with all these numbers and more using --param to adjust things with names like max-inline-insns-auto (but you need a pretty good reason to; the defaults are sound). Changing the difference between the numbers for explicit and auto inlining means you can effectively make inline have more or less of an effect though. – timday Jun 02 '09 at 21:10
0

Whether to inline is up to the compiler. Is it free to ignore the inline hint. Some compilers have a specific keyword (like __forceinline in VC++) but even with such a keyword virtual calls to virtual member functions will not be inlined.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
0

I faced similar problems and found that it only works if the inline function is written in a header file.

sybreon
  • 3,128
  • 18
  • 19
  • Why the downvote? sybreon is correct, in the case that the inlined function is called from another module... – bitsmack Aug 14 '14 at 17:00