2

In gcc, using

  • -E gives the preprocessed code;
  • -S, the assembly code;
  • -c, the code compiled, but not linked.

Is there anything close to a -I, that would allow me to see whether a function has been inlined or not, i.e., to see the code expanded, as though inline functions were preporcessed macros?

If not, should I get my way through the assembly code, or are the inline applications performed later?

Rubens
  • 14,478
  • 11
  • 63
  • 92

3 Answers3

2

I think examining the assembly code is the best (and pretty much the only) way to see what's been inlined.

Bear in mind that, in certain circumstances, some inlining can take place at link time. See Can the linker inline functions?

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

You can use the -Winline option to see whether a function can not be inlined and it was declared as inline.

Quoted from http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options

-Winline Warn if a function that is declared as inline cannot be inlined. Even with this option, the compiler does not warn about failures to inline functions declared in system headers. The compiler uses a variety of heuristics to determine whether or not to inline a function. For example, the compiler takes into account the size of the function being inlined and the amount of inlining that has already been done in the current function. Therefore, seemingly insignificant changes in the source program can cause the warnings produced by -Winline to appear or disappear.

However, inline is not a command, whether inline a function or not(though declared as inline) is decided by the compiler. It may consider the size of the function being inlined and how many times inline already been done in the current function.

The best way to see whether a function has really been inlined is to check the assembly code. For example, you can use

gcc -O2 -S -c foo.c

to generate assembly code for foo.c and output assembly code file foo.s.

taocp
  • 23,276
  • 10
  • 49
  • 62
-1

The issue here is that generally inlining is a link time optimaztion (when there are multiple object files) as the compiler simply doesn't see the implementation of functions in other object files, until link time.

Hence in multi object file compiles your best shot is to inspect the generated assembly, however within every single object file, the inlining is possible, assuming the function to be inlined is in the same compilation unit, however most compilers do not do inlining at this point, as it doesnt know where this function may be called from, and whether it should itself be inlined.

So in general inlining is performed on linking, however for very small functions, it can and should be done at compilation time.

Also I do believe that if you compile your code with clang/llvm, you'll get a c output file with inlining, tho I haven't tried it.

Do note that in order to get GCC to do the link time optimization (including inlining) you'll have to provide it with an argument, I think its -flto.

An alternative is to have all your inline functions visible in your all of your compilation units (e.g. In the header files), this will actually usually ensure inlining in order to avoid multiple declarations of the same function, in different object files.

Also an easy way to check the assembly for inlining is to compare the number of calls to the function in the source code to the number of calls in the assembly.

Skeen
  • 4,614
  • 5
  • 41
  • 67
  • Inlining can and does also happen within a single translation unit. True, this is mostly useful for `static`/`inline`/`namespace {}` functions, but quite a bit of code that should be inlined is (intentionally) placed in those. –  Mar 29 '13 at 13:41
  • Most compilers do do inlining while compiling a single translation unit. The fact that a function might be called from another module is irrelevant: If the function has external linkage, then the compiler can both inline it in calls within the unit and provide a copy that can be called externally. – Eric Postpischil Mar 29 '13 at 13:45