49

I know that inline function are either replaced where it is called or behave as a normal function.

But how will I know whether inline function is actually replaced at the place where it is called or not as decision of treating inline function as inline is at the compile time?

Abhineet
  • 6,459
  • 10
  • 35
  • 53

10 Answers10

72

Programatically at run-time, You cannot.
And the truth of the matter is: You don't need to know

An compiler can choose to inline functions that are not marked inline or ignore functions marked explicitly inline, it is completely the wish(read wisdom) of the compiler & You should trust the compiler do its job judiciously. Most of the mainstream compilers will do their job nicely.

If your question is purely from a academic point of view then there are a couple of options available:


Analyze generated Assembly Code:

You can check the assembly code to check if the function code is inlined at point of calling.

How to generate the assembly code?

For gcc:
Use the -S switch while compilation.
For ex:

g++ -S FileName.cpp

The generated assembly code is created as file FileName.s.

For MSVC:
Use the /FA Switch from command line.

In the generated assembly code lookup if there is a call assembly instruction for the particular function.


Use Compiler specific Warnings and Diagnostics:

Some compilers will emit a warning if they fail to comply an inline function request.
For example, in gcc, the -Winline command option will emit a warning if the compiler does not inline a function that was declared inline.

Check the GCC documentation for more detail:

-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.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • You mean while debugging, in assembly code section, i need to check whether the inline function is behaving as an inline or not. Something like if at the assembly side if this function is pushed and popped out etc...then it will be behaving as a normal function else inline.. – Abhineet May 17 '12 at 07:06
  • @Abhineet: Yes, or you can use compiler specific flags which warn of not being ably to complying to `inline` requests. – Alok Save May 17 '12 at 07:08
  • +1 for `-Winline`. [Here](https://stackoverflow.com/questions/8381293/how-do-i-force-gcc-to-inline-a-function#comment-10465757) you have the non-academic reason to check it and to force inlinig. (..networking/serialization library where it wont inline functions by default because of code size..) – fider Jun 23 '17 at 13:30
  • 8
    `You don't need to know` Not necessarily. If you want a helper function that wraps assembly code, it very much matters. – Alexander Oct 27 '17 at 14:24
  • in `gcc, the -Winline` - how do thain `cl`? – ilw Nov 15 '17 at 11:00
  • In default mode, `gcc` doesn't inline functions at all and `-Winline` doesn't inform about that fact. `gcc file.c -Winline` will compile without warnings, and all inline specifiers will be ignored. `-Winline` works properly only when optimisation flag is enabled (`-O1`, `-O2`, etc.). – Przemek Jun 01 '18 at 15:25
  • 4
    You aren't right about "You don't need to know". In my code I use stack overflow guards, so in case when a function gets inlined the checking code is an excessive overhead. So I want to know... – Alexey May 20 '19 at 06:43
  • 4
    `You don't need to know` Once more I will add, BS. Don't tell us what we do and don't need to know, you'll likely frequently be wrong. In my case, it's for crucially fast code, and I do need to know what it's going to do. – Andrew Feb 04 '21 at 01:16
  • @Przemek Thats pretty shocking. Is there any source where I can read about how this works ? I have been banging my head on this for hours. – Harish Ganesan Dec 05 '22 at 12:09
  • I believe you can also use `perf report --inline` to check this https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/perf-report.txt pretty sure run your program and `perf record` then add your source code to the buildid cache and then when you run perf report you should be able to drill down into the source code and see what's inlined and how. I haven't actually tried this so YMMV. – Ace.C Jan 30 '23 at 20:09
12

Check the generated code. If the function is expanded, you'll see its body, as opposed to a call or similar instruction.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
9

You can use tools for listing symbols from object files such as nm on Linux. If the function was inlined, it will not be listed in nm output - it became part of some other function. Also you will not be able to put breakpoint on this function by name in debugger.

ks1322
  • 33,961
  • 14
  • 109
  • 164
  • 5
    The same function might be inlined at one calling instance and may not be inlined at another, it entirely depends on the compiler.So using `nm` is not a reliable way of determining if the function call was indeed inlined. – Alok Save May 17 '12 at 08:17
  • 7
    @Als: Ok, if the function is absent in `nm` output, this means that all it's instances were inlined. Still it gives some information about inlining. – ks1322 May 17 '12 at 08:40
  • 1
    Yes,it gives some information, I wanted to make it clear that using `nm` tells you if **all** calling instances of a function in an translation unit were `inline`d or not, it doesn't give the information whether a **particular** calling instance was `inline`d. – Alok Save May 18 '12 at 02:55
9

If you need to make sure that function is inlined and OK to go with proprietary extension in MS VC++, check out the __forceinline declarator. The compiler will either inline the function or, if it falls into the list of documented special cases, you will get a warning - so you will know the inlining status.

Not endorsing it in any way.

Vlad Didenko
  • 4,481
  • 4
  • 25
  • 34
  • 4
    Yes, `__forceinline` removes the compiler's cost/benefit calculation, and inlines the function if it is possible. It's important to note that it *only* disables the cost/benefit calculation, but doesn't 100% guarantee that it gets inlined. – antiHUMAN Apr 18 '16 at 12:51
6

With gdb, if you cannot call to a function, one of its possible meanings is the function is inline. Flipping the reasoning, if you can call a function inside gdb, means the function is not marked inline.

ABu
  • 10,423
  • 6
  • 52
  • 103
3

The decision to inline or not a function is made by compiler. And since it is made by compiler, so YES, it can be made at compile time only.

So, if you can see the assembly code by using -S option (with gcc -S produces assembly code), you can see whether your function has been inlined or not.

1

There is a way to determine if a function is inline programmatically, without looking at the assembly code. This answer is taken from here.

Say you want to check if a specific call is inlined. You would go about like this. Compiler inlines functions, but for those functions that are exported (and almost all function are exported) it needs to maintain a non-inlined addressable function code that can be called from the outside world.

To check if your function my_function is inlined, you need to compare the my_function function pointer (which is not inlined) to the current value of the PC. Here is how I did it in my environment (GCC 7, x86_64):

void * __attribute__((noinline)) get_pc () { return _builtin_return_address(0); }

void my_function() {
    void* pc = get_pc();
    asm volatile("": : :"memory");
    printf("Function pointer = %p, current pc = %p\n", &my_function, pc);
}
void main() {
    my_function();
}

If a function is not inlined, difference between the current value of the PC and value of the function pointer should small, otherwise it will be larger. On my system, when my_function is not inlined I get the following output:

Function pointer = 0x55fc17902500, pc = 0x55fc1790257b

If the function is inlined, I get:

Function pointer = 0x55ddcffc6560, pc = 0x55ddcffc4c6a

For the non-inlined version difference is 0x7b and for the inlined version difference is 0x181f.

Bogi
  • 2,274
  • 5
  • 26
  • 34
0
  1. see the size of object files, they are different between inlined and not inlined
  2. use nm "obj_file" | grep "fun_name", they are also different
  3. gcc -Winline -O1
  4. compare with assembly code
李鹏程
  • 81
  • 1
  • 4
  • Also, if inlining is supposed to affect run-time, then compare the run-time with and without `__attribute__ ((noinline))` in the function definition right after the return type (note that this is `gcc`-specific). – AlwaysLearning Feb 24 '17 at 12:27
-1

Above answer are very mush useful, I am just adding some point which we keep in our mind while writing inline function.

Remember, inlining is only a request to the compiler, not a command. Compiler can ignore the request for inlining. Compiler may not perform inlining in such circumstances like:

1) If a function contains a loop. (for, while, do-while)

2) If a function contains static variables.

3) If a function is recursive.

4) If a function return type is other than void, and the return statement doesn’t exist in function body.

5) If a function contains switch or goto statement.

Complete info: https://www.geeksforgeeks.org/inline-functions-cpp/

-1

The compiler does not make a function inline if the function returns an address.

pkthapa
  • 1,029
  • 1
  • 17
  • 27