__inline functions vs normal functions in C

12,796

Solution 1

Inlining a function can have several advantages:

  1. It can make the program size smaller. This is typically the case when a function is only used once. Also, see 2. and 3.

  2. The compiler can eliminate unused bits of the function, if the compiler knows that a variable is constant, or non-NULL, or something like that. This can save size, but also makes the code more efficient at run time.

  3. The compiler can eliminate bits of the calling function, or even other inlined functions because it can see what the function does with/to the data. (Say the code checks the return value and calls an error function if it's NULL, it might be able to rule that out.

  4. It can reduce the call overhead, but in current processors with predictive branching that's not as much of a win as you might think.

  5. It can hoist constant bit out of loops, do common subexpression elimination, and many other optimizations to make looping code more efficient, and such like.

And then there's the disadvantages:

  1. It can make the code larger, obviously.

  2. It can increase register pressure within the calling function which might confuse the compiler and prevent it optimizing as well.

  3. Having one hot function that can live in the CPU cache can be quicker than duplicating it to many places that are not always cached.

  4. It can hamper debugging.

The reason that the inline function is just a hint is mostly because the C standard does not require that the compiler optimize anything at all. If it wasn't a hint then optimization wouldn't be optional. Also, just because the function isn't marked inline doesn't stop the compiler inlining it if it calculates that doing so would be advantageous.

Solution 2

Generally the compiler will choose to inline if it decides that the performance will be better. So it has to compare the cost of actually calling the non-inline function (pushing arguments onto stack, saving registers etc) is more than the the code itself. So for simple accessors, or simple calculations it is often the case that the cost of calling a function is more, hence the compiler will inline.

Often compilers have size constraints too so that they don't allow inlining to grow the code too much.

There is also locality to be considered. An inlined function will not likely cause a page fault, will likely not cause a processor cache miss, so will generally be faster from that point of view. Non-inlined functions will often require code to be loaded into the processor cache, which is very slow by comparison.

There are other reasons for declaring functions to be inline, even though you don't really expect the compiler to inline them. The entire STL in C++ is inlined, even though it is unlikely that most of it would ever actually be inlined. It is done this way for reasons of template instantiation, and issues to do with application binary interfaces and so on.

Solution 3

The benefits of inlining a function is removing the function call overhead and giving the optimizer a better chance of optimizing the calling code with the function code. For example, the optimizer may completely eliminate the inlined code under some circumstances.

The drawback is the possibility of increasing your code size which under certain circumstances can also slow down the execution speed if the bottleneck is CPU instruction fetch.

So it depends. Compilers use various heuristics to figure out if inlining a function is a net benefit. A compiler may inline a function even if you don't specifiy the inline keyword or it may not inline if you do. There are usually ways of forcing a compiler to inline the function to override its decision.

This What are good heuristics for inlining functions? has a good discussion and further links regarding inlining heuristics.

Solution 4

There is a pretty good overview of gcc's inlining options and the decision processes at GNU GCC.

That identifies the cases where inlining is not possible: "use of varargs, use of alloca, use of variable sized data types, use of computed goto, use of nonlocal goto, and nested functions"

An important point is a non-static function, i.e one with extern linkage (which is every functions which is declared without static) may be called, or have its address taken in a different source file.

This forces the compiler to generate a 'normal' function as well as any inlined function bodies. This, of course, generates a program which is bigger than only generating the 'normal' non-inline function.

Gcc has an option -ffunction-sections which generate object files which enable the linker to eliminate functions which are not used, at the cost of "... the assembler and linker will create larger object and executable files and will also be slower."

On more recent versions of gcc, Link Time Optimisations (LTO) (see "Whole Program Optimizations") is supported. This allows an optimisation stage to look at all the compiled program, and do even more aggressive inlining and optimisation, and exclude unused code.

It is also interesting to look at some of the newer gcc-4.6 gcc-4.7 Interprocedural optimisations. For example inline-ing only the 'hot path' of an inline function, rather than the whole function. Gcc might also generate multiple instances of one function because constants are known, and gcc calculates it is better to have multiple implementations, each optimised for those known constants.

There are options in gcc to ask for the compiler to inline all “simple enough” functions.

Finally it says "As required by ISO C++, GCC considers member functions defined within the body of a class to be marked inline even if they are not explicitly declared with the inline keyword". In which case its rule for "simple enough" is used.

Summary: the compiler might do very clever optimisations above and beyond what might be expected from ordinary functions or inline functions.

Solution 5

When you use a inline function, the function code is pasted in the line when is called, it generates too a executable program bigger than the one which doesn't use inline functions, in the other hand, a no inline function, when is called, the program stop and jumps to the memory dir where the function code start...

Conclusion: inline function = better performance, more space funcion = less space, a slight less performance

Share:
12,796
Abhishek Gupta
Author by

Abhishek Gupta

I am a student with interest in everything

Updated on June 04, 2022

Comments

  • Abhishek Gupta
    Abhishek Gupta about 2 years

    I am studying macros and found many sources and questions regarding difference between macros and inline functions. But there is nothing which concretely specifies and differentiates pros&cons of inline vs normal functions.

    But what about if I want to select between normal function and inline function?

    I know that use of inline function increase the code size. But as while studying size is not the primary issue , efficiency is the goal. Making a function an inline function suggests that calls to the function be as fast as possible.(Due to stack and stuff overhead)

    Is always using inline function is better or not? If not then WHY? What are the benefits of using normal functions over inline?

    While reading other questions I read that inline is only a hint to compiler. Compiler may ignore it. When does compiler ignore it and WHY?

  • Abhishek Gupta
    Abhishek Gupta about 12 years
    I have already mentioned that.. I am asking for any other difference , if exists.
  • Abhishek Gupta
    Abhishek Gupta about 12 years
    I don't understand why you are repeating same thing which i have already mentioned
  • David Heffernan
    David Heffernan about 12 years
    @knoxxs Berating the people that are trying to help you isn't really a good policy.
  • Guy Sirton
    Guy Sirton about 12 years
    @knoxxs: I'm not just repeating what you said. I am also saying that code increase may result in reduced performance so there's more to inlining than simply code size. It may increase or decrease code size and it may increase or decrease performance.
  • Abhishek Gupta
    Abhishek Gupta about 12 years
    Nice, I think you are on the inline side. But "often compilers have size constraints"- can you elaborate on that. I think size constraints are for OS or system not compiler
  • Abhishek Gupta
    Abhishek Gupta about 12 years
    If you want then pls elaborate on the size constraint part and I think Brett's comment is my answer.
  • Abhishek Gupta
    Abhishek Gupta about 12 years
    What is -"non-static function may have its address taken". I have searched ,but found nothing. Can you suggests anything
  • gbulmer
    gbulmer about 12 years
    All functions which are declared without the word static are non-static. This means the function is extern linkage, and hence is visible outside of the file (compilation unit) to all of the rest of the program. That means the compiler must generate a 'normal' function in case the function is called elsewhere, or even that something takes its address (so it need not be called). The linker may eliminate the generated extern function if the function is never called, and its address is not taken.
  • Brian McFarland
    Brian McFarland about 12 years
    +1 for the last comment about the compiler inlining when a function is NOT marked inline. For info on what GCC does (as an example), see gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html. Most of the time, I don't bother with the inline hint, and just use optimization flags in Makefile to inline as the compiler sees fit.
  • ams
    ams about 12 years
    The linker can only eliminate functions if the code was compiled with -ffunction-sections and linked with --gc-sections. The compiler options -fwhole-program and -flto are also able to eliminate unused extern functions (not to mention inline functions from other C files).
  • ams
    ams about 12 years
    The compiler has a set of options for controlling what size function can be inlined. For example, --param max-inline-insns-single=<num> controls inlining of functions that are called from only one place. There are several like this.
  • gbulmer
    gbulmer about 12 years
    @ams - yes, worth adding. Thanks.