262

I know that inline is a hint or request to the compiler and is used to avoid function call overheads.

So, on what basis one can determine whether a function is a candidate for inlining or not? In which case one should avoid inlining?

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
Ashish
  • 8,441
  • 12
  • 55
  • 92
  • 15
    `inline` is to the C++ newcomer what `CFLAGS` are to the Gentoo newcomer: no, compiling with `-O3 -funroll-loops -finline-functions` won't make your old Pentium fly ;) – Gregory Pakosz Dec 19 '09 at 08:43
  • 1
    Duplicate: http://stackoverflow.com/questions/1875947/benefits-of-declaring-a-function-as-inline – Steve Jessop Dec 19 '09 at 16:02
  • 8
    You shouldn't determine whether a function should be inlined or not. Let the compiler do it; it's better at it than you are (and can inline functions selectively based on the environment of each call). – David Thornley Dec 20 '09 at 18:42
  • 2
    A reason not to use inline is that some debuggers won't allow you to set a break point or step into an inlined function. – Rob deFriesse Dec 19 '09 at 15:11
  • @DavidThornley Sometimes, even with O3 flag set, the compiler does not inline the function if the definition is in cpp file. So, the thumb rule that I follow is to inline one liners and also those functions without any loops. – talekeDskobeDa Nov 11 '19 at 16:36
  • @talekeDskobeDa you can enable link time optimization if you want functions in cpp files to be optimized – Volper Dec 01 '20 at 09:05

14 Answers14

271

Avoiding the cost of a function call is only half the story.

do:

  • use inline instead of #define
  • very small functions are good candidates for inline: faster code and smaller executables (more chances to stay in the code cache)
  • the function is small and called very often

don't:

  • large functions: leads to larger executables, which significantly impairs performance regardless of the faster execution that results from the calling overhead
  • inline functions that are I/O bound
  • the function is seldom used
  • constructors and destructors: even when empty, the compiler generates code for them
  • breaking binary compatibility when developing libraries:
    • inline an existing function
    • change an inline function or make an inline function non-inline: prior version of the library call the old implementation

when developing a library, in order to make a class extensible in the future you should:

  • add non-inline virtual destructor even if the body is empty
  • make all constructors non-inline
  • write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value

Remember that the inline keyword is a hint to the compiler: the compiler may decide not to inline a function and it can decide to inline functions that were not marked inline in the first place. I generally avoid marking function inline (apart maybe when writing very very small functions).

About performance, the wise approach is (as always) to profile the application, then eventually inline a set of functions representing a bottleneck.

References:


EDIT: Bjarne Stroustrup, The C++ Programming Language:

A function can be defined to be inline. For example:

inline int fac(int n)
{
  return (n < 2) ? 1 : n * fac(n-1);
}

The inline specifier is a hint to the compiler that it should attempt to generate code for a call of fac() inline rather than laying down the code for the function once and then calling through the usual function call mechanism. A clever compiler can generate the constant 720 for a call fac(6). The possibility of mutually recursive inline functions, inline functions that recurse or not depending on input, etc., makes it impossible to guarantee that every call of an inline function is actually inlined. The degree of cleverness of a compiler cannot be legislated, so one compiler might generate 720, another 6 * fac(5), and yet another an un-inlined call fac(6).

To make inlining possible in the absence of unusually clever compilation and linking facilities, the definition–and not just the declaration–of an inline function must be in scope (§9.2). An inline especifier does not affect the semantics of a function. In particular, an inline function still has a unique address and so has static variables (§7.1.2) of an inline function.

EDIT2: ISO-IEC 14882-1998, 7.1.2 Function specifiers

A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.

Gregory Pakosz
  • 69,011
  • 20
  • 139
  • 164
  • 42
    `inline` is much more than a hint to the compiler. It changes the language rules about multiple definitions. Also, having static data isn't a cast iron reason to avoid inlining a function. The implementation is obliged to allocate a single static object for each function static whether or not the function is declared `inline` or not. Classes are still extensible if they have inline constructors and virtual destructors. And empty brace destructor is the one virtual function that it is _sometimes_ a good idea to leave inline. – CB Bailey Dec 19 '09 at 10:49
  • 2
    It's a hint in the sense the function doesn't necessarily ends up inlined (but english isn't my mother tongue). About statics in functions marked `inline`, the result is that the function doesn't get inlined: you pay the price for the call and also each translation unit that includes and calls the function gets its own copy of the code and static variables. The reason for not inlining constructors and destructors when developing a library is binary compatibility with future versions of your library – Gregory Pakosz Dec 19 '09 at 11:06
  • @Gregory: Functions with statics can be inlined, its just the actions on the static object which must refer to the same 'global' object; it's required by the standard. W.r.t. binary compatibility I agree with your reasons, but it's a whole other story. The fact that new private data members break binary compatibility usually puts other concerns in the shade. For long lived binary compatibility you often end up having to "pimpl" most interesting objects anyway, rendering the inline discussion irrelevant. – CB Bailey Dec 19 '09 at 11:37
  • @Charles, I edited the answer. I had in mind old compilers treating an un-inlined function as if it had been declared `static`. Indeed conformant compilers will get it right but it was a "better safe than sorry" approach. Still the problem might arise when one misuses `static` on a function so that it becomes private instead of putting it in an anonymous namespace. About pimpl, agreed. – Gregory Pakosz Dec 19 '09 at 12:41
  • 17
    It's inaccurate to call it a "hint to the compiler". In reality, non-`inline` functions can be inlined if the compiler feels like it. And `inline` functions won't be inlined if the compiler decides not to inline them. As Charles Bailey said, it changes the language rules. Rather than thinking of it as an optimization hint, it is more accurate to think of it as a completely different concept. The `inline` keyword tells the compiler to allow multiple definitions, and nothing else. The "inlining" optimization can be applied to almost any function, whether or not it's marked `inline`. – jalf Dec 20 '09 at 02:08
  • I don't see how why my descriptive answer is summed up as "thinking of it as an optimization hint" and I may be blind but what you're saying in your comment about the compiler being fee to decide what gets inline and what not; I wrote it at the end of my answer. And as per http://thefreedictionary.com/hint a "hint" means "a slight indication" – Gregory Pakosz Dec 20 '09 at 08:37
  • Yes, but the point is that it is not "a slight indication", but rather a way to get your code to *compile and link successfully where it would otherwise result in an error*. That is the purpose of the `inline` keyword. – jalf Dec 20 '09 at 14:37
  • 35
    It's just that, when Stroustrup writes "the inline specifier is a hint to the compiler", I'm surprised I'm blamed for quoting him. Anyway, I spent enough time doing my best to back this answer with as much references as possible – Gregory Pakosz Dec 20 '09 at 14:54
  • @Gregory Pakosz , why should we avoid inlining a I/O bounded function, i mean, CPU still has got to execute those I/O bounded codes, and btw, if code size enlargement is not considered, inlining does eliminate the function call overhead. – Tracy Oct 05 '12 at 03:02
  • @Tracy code is data, if it's I/O bound, inlining doesn't speed it up so don't pay the code cache trash tax – Gregory Pakosz Oct 05 '12 at 06:57
  • 2
    @GregoryPakosz: But we don't all use `inline` in order to obtain function inlining. Sometimes we want the other benefits, like getting around ODR. – Lightness Races in Orbit May 31 '13 at 13:28
  • @GregoryPakosz: Sir, what do you mean by saying that "Avoiding the cost of a function call is only half the story." ? Please explain it more clearly. are you saying about optimizations? – Destructor Apr 25 '15 at 10:37
71

inline has very little to do with optimization. inline is an instruction to the compiler not to produce an error if the function given definition occurs multiple times in the program and a promise that the definition will occur in every translation that it is used and everywhere it does appear it will have exactly the same definition.

Given the above rules, inline is suitable for short functions whose body doesn't necessitate including extra dependencies over what just a declaration would need. Every time the defintion is encountered it must be parsed and code for its body may be generated so it implies some compiler overhead over a function defined only once in a single source file.

A compiler may inline (i.e. replace a call to the function with code that performs that action of that function) any function call that it chooses. It used to be the case that it "obviously" couldn't inline a function that wasn't declared in the same translation unit as the call but with the increasing use of link time optimization even this isn't true now. Equally true is the fact that functions marked inline may not be inlined.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 1
    I get the feeling that this is more of a happy coincidence than an intentional feature of C++. The idea is very similar to the 'static' global variables from C. It's a very interesting answer though. I wish they'd just used a keyword like 'internal' to indicate internal linkage. – Rehno Lindeque Dec 19 '09 at 12:39
  • 1
    +1. @Rehno: I'm not really sure what you're saying. What does linkage have to do with the `inline` keyword? And what is a happy coincidence? – jalf Dec 20 '09 at 02:09
  • @jalf: Reading my comment in retrospect I realize it is rather vague and not that well thought out. Defining the same function in multiple files results a linker error which can be countered by declaring the function 'static'. However, 'inline' allows you to do the same thing with subtle differences that they do not actually get internal linkage like 'static' does. I suspect that this is actually more a coincidence because language implementers/designers realized that they'll need to do something special with functions declared in header files and that carried over to 'inline'. – Rehno Lindeque Dec 20 '09 at 20:09
  • 5
    Not sure why your comment got so many up votes, since performance is the dominant reason to use inline. – gast128 Aug 21 '17 at 10:29
  • 2
    @gert128 "Premature optimization is the root of all evil" if you're concerned about performance, just add `-O3` to the compiler flags and the compiler will figure out what to inline by itself. Don't add keywords and expect them to make your code faster. I've heard a lecture about optimization and the lecturer who worked in LLVM said that the inline keyword doesn't have much to do with optimization. It's just about the semantics / language rules – Volper Dec 01 '20 at 09:00
15

Telling the compiler to inline a function is an optimization, and the most important rule of optimization is that premature optimization is the root of all evil. Always write clear code (using efficient algorithms), then profile your program and only optimize functions that are taking too long.

If you find a particular function is very short and simple, and it's getting called tens of thousands of times in a tight inner loop, it might be a good candidate.

You might be surprised, though - many C++ compilers will automatically inline small functions for you - and they might ignore your request to inline, too.

dmazzoni
  • 12,866
  • 4
  • 38
  • 34
  • Indeed, I have my suspicions that certain compilers very sneakily ignore 'inline' completely and only respond to '__inline' or '__force_inline'. I suppose this is to deter abuse! – Rehno Lindeque Dec 19 '09 at 08:58
  • Not usually the case. inline is only a hint, but it's a hint most compilers take seriously. You can set the compiler to emit the assembly language along with the object code (`/FAcs` in Visual Studio, `-s` in GCC) to see exactly what it does. In my experience, both those compilers weigh the inline keyword quite heavily. – Crashworks Dec 19 '09 at 10:00
  • 1
    It's interesting, because in my experience neither g++ nor VC weigh `inline` keyword at all. That is, if you see the function being inlined, and remove `inline` specifier from it, it will still get inlined. If you have any specific examples of the opposite, please share them! – Pavel Minaev Dec 19 '09 at 10:02
  • I meant the opposite case more: the compiler is free to inline anything it likes, but it's rare that I see it choose *not* to inline something I told it to `inline`. The typical case I use here is get/set functions (which I inline in the .h rather than define in a .cpp), and 3d vector operations. For some reason, functions like dot/cross product, orthonormalization, etc seem to be just at the threshold where MSVC won't inline them on its own, but will respect the `inline` keyword. – Crashworks Dec 19 '09 at 10:07
  • I could be wrong I'm sure. I think I once saw '#define inline' in one of the standard header files, but it could have just been some backward compatibility flag for C. Also it is true that the compiler can inline any function it chooses to. – Rehno Lindeque Dec 19 '09 at 12:20
  • 7
    how does the `inline` keyword hinder "clear code"? The keyword in "premature optimization" is *premature*, not *optimization. Saying that you should actively *avoid* optimizations is just rubbish. The point of that quote is that you should avoid the optimizations that may not be necessary, and have harmful side effects on the code (such as making it less maintainable). I fail to see how the `inline` keyword is going to make the code less maintainable, or how it can be harmful to add it to a function. – jalf Dec 20 '09 at 02:11
  • 3
    jalf, sometimes inlining a function will make your code slower, not faster. One example is when the function is called from several different places in your code; if the function is not inlined, then it might still be in the instruction cache when it's called from a different place, and the branch predictor might already be warmed up. There are some patterns that always improve efficiency, so it never hurts to use them. Inlining is not one of them. It usually has no effect on performance at all, it sometimes helps, and sometimes hurts. I stand behind my advice: profile first, then inline. – dmazzoni Dec 21 '09 at 06:04
  • Inlining is sometimes negative, but it can also be an *immense* performance gain under the right circumstances. I've measured it: http://assemblyrequired.crashworks.org/2009/01/19/how-slow-are-virtual-functions-really/ – Crashworks Dec 22 '09 at 01:27
6

Premature optimization is the root of all evil!

As a rule of thumb I usually inline only "getters" and "setters". Once the code is working and is stable, profiling can show which functions could benefit from inlining.

On the other hand, most modern compilers have quite good optimization algorithms, and will inline what you should have inlined for you.

Reasuming -- write inline one-liner functions, and worry about others later.

Kornel Kisielewicz
  • 55,802
  • 15
  • 111
  • 149
5

The best way to find out is to profile your program and mark small functions that get called lots of times and burn through CPU cycles that as inline. The keyword here is "small" - once the function call overhead is negligible compared to the time spent in the function, it's pointless to inline them.

The other use I'd suggest is if you've got small functions that get called in performance critical code often enough to make a cache miss relevant, you should probably inline those as well. Again, it's something the profiler should be able to tell you.

Timo Geusch
  • 24,095
  • 5
  • 52
  • 70
3

I often use inline functions not as an optimization but to make the code more readable. Sometimes the code itself is shorter and easier to understand than comments, descriptive names etc. For example:

void IncreaseCount() { freeInstancesCnt++; }

The reader immediately knows the complete semantics of the code.

danatel
  • 4,844
  • 11
  • 48
  • 62
1

Inline functions might improve your code performance by eliminating the need to push arguments into the stack. if the function in question is in a critical part of your code you should make the inline not inline decision in the optimization part of your project,

you can read more about inlines in the c++ faq

jball
  • 24,791
  • 9
  • 70
  • 92
Alon
  • 4,862
  • 19
  • 27
1

The best way would be to examine and compare the generated instructions for inlined and not inlined. However, it is always safe to omit inline. Using inline could lead to trouble you don't want.

wallyk
  • 56,922
  • 16
  • 83
  • 148
1

One should use the inline function qualifier only when the function code is small.If the functions are larger you should prefer the normal functions since the saving in memory space is worth the comparatively small sacrifice in execution speed.

nitish
  • 37
  • 4
0

I generally follow a thumb rule where I make a function with 3-4 simple statements as inline. But it is good to remember that it is just a hint to the compiler. The final call to make it inline or not is taken by the compiler only. If there are more than these many statements I will not declare inline as with a stupid compiler it may lead to code bloat.

Naveen
  • 74,600
  • 47
  • 176
  • 233
0

When deciding on whether to use inline, I usually keep the following idea in mind: On modern machines memory latency can be a bigger bottleneck than raw calculations. Inlining functions that are called often is known to grow the executable size. Furthermore, such a function could be stored in the CPU's code cache which will decrease the number of cache misses when that code needs to be accessed.

Hence, you have to decide for yourself: Does inlining increase or decrease the size of the generated machine code? How likely is it that calling the function will cause a cache miss? If it is peppered throughout the code, then I would say the likelihood is high. If it is restricted to a single tight loop then the likelihood is hopefully low.

I typically use inlining in the cases I list bellow. However, where you are genuinely concerned about performance, profiling is essential. Furthermore, you might want to check whether the compiler actually takes the hint.

  • Short routines that are called in a tight loop.
  • Very basic accessors (get / set) and wrapper functions.
  • Template code in header files unfortunately automatically obtain the inline hint.
  • Short code that is used like a macro. (E.g. min() / max())
  • Short math routines.
Rehno Lindeque
  • 4,236
  • 2
  • 23
  • 31
  • "Premature optimization is the root of all evil" if you're concerned about performance, just add `-O3` to the compiler flags and the compiler will figure out what to inline by itself. Don't add keywords and expect them to make your code faster. I've heard a lecture about optimization and the lecturer who worked in LLVM said that the inline keyword doesn't have much to do with optimization. It's just about the semantics / language rules – Volper Dec 01 '20 at 09:03
0

Also, an inline method has severe side effects when maintaining large projects. When the inline code is changed, all files that use it will be rebuild automatically by the compiler (it it is a good compiler). This could waste a lot of your development time.

When an inline method is transferred to a source file and not inlined any more, the whole project must be rebuilt (at least this has been my experience). And also when methods are converted to inline.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • 1
    That's a different issue. You get the rebuild problem for code that is placed in a header file. Whether it is marked `inline` or not doesn't matter (other than without the `inline` keyword, you'll get linker errors - but the `inline` keyword is not the issue causing excessive rebuilds. – jalf Dec 20 '09 at 02:12
  • 1
    However, changing an inline method will cause excessive builds versus changing a non-inline method in a shource file. – Thomas Matthews Dec 20 '09 at 07:44
0

When you think your code is small enough to be used as inline and remember inline function duplicate your code and paste it were the function is called so it may be good enough to increase your execution time but increased memory consumption also. You can't use inline function when you are using a loop/static variable/recursive/switch/goto/Virtual function. Virtual means wait until runtime and inline means during compilation so they can't be use simultaneously.

-2

I have read some answers and see that there some stuff missing.

The rule I use is not to use inline, unless I want it to be inline. Looks silly, now explanation.

Compilers are smart enough and short functions always makes inline. And never makes long function as inline, unless programmer said to do that.

I know that inline is a hint or request to compiler

Actually inline is an order for compiler, it has no choices and after inline keyword makes all code inline. So you can never use inline keyword and compiler will design shortest code.

So when to use inline?

To use if you want to have some code inline. I know only one example, because I use it in only one situation. It is user authentication.

For example I have this function:

inline bool ValidUser(const std::string& username, const std::string& password)
{
    //here it is quite long function
}

No matter how big this function is I want to have it as inline because it makes my software harder to crack.

ST3
  • 8,826
  • 3
  • 68
  • 92
  • 5
    inline is still a hint. The compiler can fail to inline if it deems that your function is too bloated. – It'sPete Jul 01 '15 at 17:41
  • One says inline is an order... the other says its a hint Would someone substantiate his statement so we can determine which one is true? –  Feb 17 '17 at 22:29
  • @user2918461 i support the statement inline is just a hint. This has been supported by many websites and books – WARhead Nov 29 '17 at 16:32