What Does It Mean For a C++ Function To Be Inline?

左心房为你撑大大i 提交于 2019-11-27 07:27:14

The function is placed in the code, rather than being called, similar to using macros (conceptually)

This can improve speed (no function call), but causes code bloat (if the function is used 100 times, you now have 100 copies)

You should note this does not force the compiler to make the function inline, and it will ignore you if it thinks its a bad idea. Similarly the compiler may decided to make normal functions inline for you.

This also allows you to place the entire function in a header file, rather than implementing it in a cpp file (which you cant anyways, since then you get an unresolved external if it was declared inline, unless of course only that cpp file used it).

It means one thing and one thing only: that the compiler will elide multiple definitions of the function.

A function normally cannot be defined multiple times (i.e. if you place a non-inline function definition into a header and then #include it into multiple compilation units you will receive a linker error). Marking the function definition as "inline" suppresses this error (the linker ensures that the Right Thing happens).

IT DOES NOT MEAN ANYTHING MORE!

Most significantly, it does NOT mean that the compiler will embed the compiled function into each call site. Whether that occurs is entirely up to the whims of the compiler, and typically the inline modifier does little or nothing to change the compiler's mind. The compiler can--and does--inline functions that aren't marked inline, and it can make function calls to functions that are marked inline.

Eliding multiple definitions is the thing to remember.

As well as the other (perfectly correct) answers about the performance implications of inline, in C++ you should also note this allows you to safely put a function in a header:

// my_thing.h
inline int do_my_thing(int a, int b) { return a + b; }

// use_my_thing.cpp
#include "my_thing.h"
...
    set_do_thing(&do_my_thing);

// use_my_thing_again.cpp
...
    set_other_do_thing(&do_my_thing);

This is because the compiler only includes the actual body of the function in the first object file that needs a regular callable function to be compiled (normally because it's address was taken, as I showed above).

Without the inline keyword, most compilers would give an error about multiple definition, eg for MSVC:

use_my_thing_again.obj : error LNK2005: "int __cdecl do_my_thing(int,int)" (?do_my_thing@@YAHHH@Z) already defined in use_my_thing.obj
<...>\Scratch.exe : fatal error LNK1169: one or more multiply defined symbols found

@OldMan

The compilers only inline non marked as inline functions ONLY if you request it to do so.

Only if by "request" you mean "turn on optimizations".

Its correct only on the effcts nto the casuse.

It's correct in both.

Inline do not generate any extra info that the linker may use. Compiel 2 object files and check. It allow multiple definitions exaclty because the symbols are not exported! Not because that is its goal!

What do you mean, "the symbols are not exported"? inline functions are not static. Their names are visible; they have external linkage. To quote from the C++ Standard:

void h(); inline void h(); // external linkage

inline void l(); void l(); // external linkage

The multiple definitions thing is very much the goal. It's mandatory:

An inline function shall be defined in every translation unit in which it is used and shall have exactly the same definition in every case (3.2). [Note: a call to the inline function may be encountered before its definition appears in the translation unit. ] If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An inline function with external linkage shall have the same address in all translation units.

The function body is literally inserted inside the caller function. Thus, if you have multiple calls to this function, you get multiple copies of the code. The benefit is you get faster execution.

Usually very short function are inlined, when the copy of the function body would be not much bigger than the usual prologue/epilogue code generated for the normal function call.

You can read more at MSDN article about inline - http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx

Inline functions alter the performance profile of your application by possibly generating instructions that are placed in the code segment of your application. Whether a function is inlined is at the discretion of your compiler. In my experience, most modern compilers are good at determining when to comply with a user's request to inline.

In many cases, inlining a function will improve its performance. There is an inherent overhead to function calls. There are reasons, however, why inlining a function could be negative:

  • Increasing the size of the binary executable by duplicating code could lead to disk thrashing, slowing your application down.
  • Inlining code could contribute to cache misses, or possibly contribute to cache hits depending on your architecture.

The C++ FAQ does a good job of explaining the intricacies of the keyword: http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.3

Informally, it means that compilers are allowed to graft the contents of the function onto the call site, so that there is no function call. If your function has big control statements (e.g., if, switch, etc.), and the conditions can be evaluated at compile time at the call site (e.g., constant values used at call site), then your code ends up much smaller (the unused branches are dropped off).

More formally, inline functions have different linkage too. I'll let C++ experts talk about that aspect.

Calling a function imposes a certain performance penalty for the CPU over just having a linear stream of instructions. The CPU's registers have to be written to another location, etc. Obviously the benefits of having functions usually outweigh the performance penalty. But, where performance will be an issue, for example the fabled 'inner loop' function or some other bottleneck, the compiler can insert the machine code for the function into the main stream of execution instead of going through the CPU's tax for calling a function.

A function that you flag as inline is allowed to be inlined by the compiler. There is no guarantee that compielr will do it. The compiler itself uses complex semantics to device when to do it or not.

When the compiler decides that a function should be inlined, the call to the function, in the caller code is replaced by the code of the calee. This means you save up stack operations, the call itself and improve locality of code cache. Sometimes that may lead to huge performance gains. Specially in 1 line data access functions, like the accessors used in Object Oriented code.

The cost is that usually that will result in larger code, what might hurt performance. This is why setting a function to inline is only a "green flag" to the compiler, that it does not need to follow. The compiler will try to do what is best.

As a rule of thumb for beginners that don't want to deal with linkage peculiarities. inline function are to be called by other function in same compilation units. If you want to implement an inline function that can be used on multiple compilation units, make it an header file declared and implemented inline function.

Why?

Example: at header file inlinetest.h

int foo();
inline int bar();

At the compilation unit inlinetest.cpp

 int foo(){ int r = bar(); return r; }


 inline int bar(){ return 5;};

Then at the main.cpp

 #include "inlinetest.h"
 int main()
 {
  foo();
 //bar();
  }

Compile one object file at a time. If you uncomment that "bar" call you will have an error. Because the inline function is only implemented on the inlinetest.o object file and is not exported. At same time the foo function, very likely has embedded on it the code of the bar function (since bar is single line no I/O operation then its very likely to be inlined)

But if at the header file you had declared the inline function and implemented it inline then you would be able to use it at any compilation unit that includes that header. ("code sample");

Remove the inline keyword and compiler will NOT cause the error even with bar call at main And no inline will happen unless you ask the compiler to inline all functions. That is not standard behavior on most compilers.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!