Question

When should I write the keyword inline for a function/method in C++?

After seeing some answers, some related questions:

  • When should I not write the keyword 'inline' for a function/method in C++?

  • When will the compiler not know when to make a function/method 'inline'?

  • Does it matter if an application is multithreaded when one writes 'inline' for a function/method?

Was it helpful?

Solution

Oh man, one of my pet peeves.

inline is more like static or extern than a directive telling the compiler to inline your functions. extern, static, inline are linkage directives, used almost exclusively by the linker, not the compiler.

It is said that inline hints to the compiler that you think the function should be inlined. That may have been true in 1998, but a decade later the compiler needs no such hints. Not to mention humans are usually wrong when it comes to optimizing code, so most compilers flat out ignore the 'hint'.

  • static - the variable/function name cannot be used in other translation units. Linker needs to make sure it doesn't accidentally use a statically defined variable/function from another translation unit.

  • extern - use this variable/function name in this translation unit but don't complain if it isn't defined. The linker will sort it out and make sure all the code that tried to use some extern symbol has its address.

  • inline - this function will be defined in multiple translation units, don't worry about it. The linker needs to make sure all translation units use a single instance of the variable/function.

Note: Generally, declaring templates inline is pointless, as they have the linkage semantics of inline already. However, explicit specialization and instantiation of templates require inline to be used.


Specific answers to your questions:

  • When should I write the keyword 'inline' for a function/method in C++?

    Only when you want the function to be defined in a header. More exactly only when the function's definition can show up in multiple translation units. It's a good idea to define small (as in one liner) functions in the header file as it gives the compiler more information to work with while optimizing your code. It also increases compilation time.

  • When should I not write the keyword 'inline' for a function/method in C++?

    Don't add inline just because you think your code will run faster if the compiler inlines it.

  • When will the compiler not know when to make a function/method 'inline'?

    Generally, the compiler will be able to do this better than you. However, the compiler doesn't have the option to inline code if it doesn't have the function definition. In maximally optimized code usually all private methods are inlined whether you ask for it or not.

    As an aside to prevent inlining in GCC, use __attribute__(( noinline )), and in Visual Studio, use __declspec(noinline).

  • Does it matter if an application is multithreaded when one writes 'inline' for a function/method?

    Multithreading doesn't affect inlining in any way.

OTHER TIPS

I'd like to contribute to all of the great answers in this thread with a convincing example to disperse any remaining misunderstanding.

Given two source files, such as:

  • inline111.cpp:

    #include <iostream>
    
    void bar();
    
    inline int fun() {
      return 111;
    }
    
    int main() {
      std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
      bar();
    }
    
  • inline222.cpp:

    #include <iostream>
    
    inline int fun() {
      return 222;
    }
    
    void bar() {
      std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
    }
    

  • Case A:

    Compile:

    g++ -std=c++11 inline111.cpp inline222.cpp
    

    Output:

    inline111: fun() = 111, &fun = 0x4029a0
    inline222: fun() = 111, &fun = 0x4029a0
    

    Discussion:

    1. Even thou you ought to have identical definitions of your inline functions, C++ compiler does not flag it if that is not the case (actually, due to separate compilation it has no ways to check it). It is your own duty to ensure this!

    2. Linker does not complain about One Definition Rule, as fun() is declared as inline. However, because inline111.cpp is the first translation unit (which actually calls fun()) processed by compiler, the compiler instantiates fun() upon its first call-encounter in inline111.cpp. If compiler decides not to expand fun() upon its call from anywhere else in your program (e.g. from inline222.cpp), the call to fun() will always be linked to its instance produced from inline111.cpp (the call to fun() inside inline222.cpp may also produce an instance in that translation unit, but it will remain unlinked). Indeed, that is evident from the identical &fun = 0x4029a0 print-outs.

    3. Finally, despite the inline suggestion to the compiler to actually expand the one-liner fun(), it ignores your suggestion completely, which is clear because fun() = 111 in both of the lines.


  • Case B:

    Compile (notice reverse order):

    g++ -std=c++11 inline222.cpp inline111.cpp
    

    Output:

    inline111: fun() = 222, &fun = 0x402980
    inline222: fun() = 222, &fun = 0x402980
    

    Discussion:

    1. This case asserts what have been discussed in Case A.

    2. Notice an important point, that if you comment out the actual call to fun() in inline222.cpp (e.g. comment out cout-statement in inline222.cpp completely) then, despite the compilation order of your translation units, fun() will be instantiated upon it's first call encounter in inline111.cpp, resulting in print-out for Case B as inline111: fun() = 111, &fun = 0x402980.


  • Case C:

    Compile (notice -O2):

    g++ -std=c++11 -O2 inline222.cpp inline111.cpp
    

    or

    g++ -std=c++11 -O2 inline111.cpp inline222.cpp
    

    Output:

    inline111: fun() = 111, &fun = 0x402900
    inline222: fun() = 222, &fun = 0x402900
    

    Discussion:

    1. As is described here, -O2 optimization encourages compiler to actually expand the functions that can be inlined (Notice also that -fno-inline is default without optimization options). As is evident from the outprint here, the fun() has actually been inline expanded (according to its definition in that particular translation unit), resulting in two different fun() print-outs. Despite this, there is still only one globally linked instance of fun() (as required by the standard), as is evident from identical &fun print-out.

You still need to explicitly inline your function when doing template specialization (if specialization is in .h file)

1) Nowadays, pretty much never. If it's a good idea to inline a function, the compiler will do it without your help.

2) Always. See #1.

(Edited to reflect that you broke your question into two questions...)

When should I not write the keyword 'inline' for a function/method in C++?

If the function is defined in the .cpp file, you should not write the keyword.

When will the the compiler not know when to make a function/method 'inline'?

There is no such situation. The compiler cannot make a function inline. All it can do is to inline some or all calls to the function. It can't do so if it hasn't got the code of the function (in that case the linker needs to do it if it is able to do so).

Does it matter if an application is multithreaded when one writes 'inline' for a function/method?

No, that does not matter at all.

  • When will the the compiler not know when to make a function/method 'inline'?

This depends on the compiler used. Do not blindly trust that nowadays compilers know better then humans how to inline and you should never use it for performance reasons, because it's linkage directive rather than optimization hint. While I agree that ideologically are these arguments correct encountering reality might be a different thing.

After reading multiple threads around I tried out of curiosity the effects of inline on the code I'm just working and the results were that I got measurable speedup for GCC and no speed up for Intel compiler.

(More detail: math simulations with few critical functions defined outside class, GCC 4.6.3 (g++ -O3), ICC 13.1.0 (icpc -O3); adding inline to critical points caused +6% speedup with GCC code).

So if you qualify GCC 4.6 as a modern compiler the result is that inline directive still matters if you write CPU intensive tasks and know where exactly is the bottleneck.

In reality, pretty much never. All you're doing is suggesting that the compiler make a given function inline (e.g., replace all calls to this function /w its body). There are no guarantees, of course: the compiler may ignore the directive.

The compiler will generally do a good job of detecting + optimizing things like this.

gcc by default does not inline any functions when compiling without optimization enabled. I don't know about visual studio – deft_code

I checked this for Visual Studio 9 (15.00.30729.01) by compiling with /FAcs and looking at the assembly code: The compiler produced calls to member functions without optimization enabled in debug mode. Even if the function is marked with __forceinline, no inline runtime code is produced.

You want to put it in the very beginning, before return type. But most Compilers ignore it. If it's defined, and it has a smaller block of code, most compilers consider it inline anyway.

When developing and debugging code, leave inline out. It complicates debugging.

The major reason for adding them is to help optimize the generated code. Typically this trades increased code space for speed, but sometimes inline saves both code space and execution time.

Expending this kind of thought about performance optimization before algorithm completion is premature optimization.

When one should inline :

1.When one want to avoid overhead of things happening when function is called like parameter passing , control transfer, control return etc.

2.The function should be small,frequently called and making inline is really advantageous since as per 80-20 rule,try to make those function inline which has major impact on program performance.

As we know that inline is just a request to compiler similar to register and it will cost you at Object code size.

Unless you are writing a library or have special reasons, you can forget about inline and use link-time optimization instead. It removes the requirement that a function definition must be in a header for it to be considered for inlining across compilation units, which is precisely what inline allows.

(But see Is there any reason why not to use link time optimization?)

C++ inline function is powerful concept that is commonly used with classes. If a function is inline, the compiler places a copy of the code of that function at each point where the function is called at compile time.

Any change to an inline function could require all clients of the function to be recompiled because compiler would need to replace all the code once again otherwise it will continue with old functionality.

To inline a function, place the keyword inline before the function name and define the function before any calls are made to the function. The compiler can ignore the inline qualifier in case defined function is more than a line.

A function definition in a class definition is an inline function definition, even without the use of the inline specifier.

Following is an example, which makes use of inline function to return max of two numbers

#include <iostream>

using namespace std;

inline int Max(int x, int y) { return (x > y)? x : y; }

// Main function for the program
int main() {
   cout << "Max (100,1010): " << Max(100,1010) << endl;

   return 0;
}

for more information see here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top