About Inline Functions

Oct 3, 2008 at 10:30pm
When they are better than the normal ones?
Oct 4, 2008 at 12:40am
They aren't. But sometimes they are faster.

The difference is essentially that a normal function is "called" --meaning arguments are pushed onto the stack, the address of the next instruction is pushed on the stack, the instruction pointer is updated to point to the first instruction of the function-- the function runs, pops the return address and restores the instruction pointer-- and the caller pops the arguments off the stack.

If your function is really short then that may just be too much work. Instead of all that, a copy of the function's code is just inserted instead of a call to the function itself.

Hope this helps.
Oct 4, 2008 at 2:07am
Yes, that help :) Thanks.
Last edited on Oct 4, 2008 at 2:08am
Oct 4, 2008 at 9:43am
Don't bother using inline to avoid function calls. Use it either if your profiler told you that function aliasing is a problem, or...
... to circumvent the One-Definition-Rule. For example, if you have a data collection without a .cpp file and you want to write an 'operator<<', but you don't want an extra .cpp file just for this operator, then you have to declare it inline in the header file (if the header is part of multiple compilation units, that is).

Though this might be not the intended usage and oftentimes is "bad style", I find myself using it in the second way for more often than in the first.
Oct 4, 2008 at 9:59pm
That is very dangerous advice.

First off, function aliasing is a major part of the whole 'object-oriented programming' concept. Don't write code that fights its own structure.

Secondly, you can't defeat the One Definition Rule. Just putting a function in a header doesn't mean that it gets inlined. The compiler is smart enough to recognize that references to the same function in the same header can be deferred to a single piece of code that it automatically creates --which is the same final effect as writing that 'extra' .cpp file.

Finally, eliminating function calls makes a significant difference when speed is an issue. Use of a profiler is indeed important here --small functions that get called a lot are prime-candidates for inlining --exactly because it eliminates the time (and, often enough, space) overhead of actually calling the function instead of simply doing its job directly.

The only disadvantages to inlined functions are that every piece of code that uses them must be recompiled if you change the function's body.

Fortunately, most major compilers are pretty good at choosing which functions they will actually inline (remember, marking a function as 'inline' is a suggestion to the compiler) and which they will treat like normal functions to be compiled once and called normally by using code. A good rule of thumb is often that common functions that are less than three lines of code are OK to mark inline. Remember, though, that virtual functions (AKA aliased functions) cannot be inlined. Attempts to do so will be at best ignored and at worst the compiler will mark them as an error and make you fix their type.

BTW, using inline functions to avoid a lot of little .cpp files is perfectly legal, though you will still have the dependency problem if your function is used a lot --even if the dependent files don't actually need to be changed.
Last edited on Oct 4, 2008 at 10:01pm
Oct 5, 2008 at 7:59am
First off, function aliasing is a major part of the whole 'object-oriented programming' concept. Don't write code that fights its own structure.

Well, like it or don't, but eliminating it is the only impact of inlined functions you will get. Note also that inlining as available in C++ doesn't eliminate it on the user level, it does so on the compiler/optimizer level. And that's a Good Thing for sure.

Secondly, you can't defeat the One Definition Rule. Just putting a function in a header doesn't mean that it gets inlined.

That's one of the "right in most cases" things. It's right that the word 'inline' has little or (for most compilers) no effect on the decision of the compiler. But to quote from the ODR:
Every program shall contain exactly one definition of every non-inline function or object that is used in that program;

... where 'non-inline function' doesn't refer to what the compiler does. It refers to what the language syntax and semantic is all about. So while the compiler pretty much can do what it wants (e.g. copy it to another cpp file and make it a 'regular' function), on the language level the ODR is 'special' for inline functions.

Finally, eliminating function calls makes a significant difference when speed is an issue.

Maybe. If the code doesn't need to be copied into the cache and some other assumptions hold true. But your compiler is better with optimizations than you are, trust me that (or, if you don't, spend some time with the nice folks from the gcc project or any other major compiler vendor).
Furthermore, most people I know who optimize on the 'inline' level have little or no idea about the real speed issues of their code, which is rather in the magnitude of using bubble sort instead of something faster.

Remember, though, that virtual functions (AKA aliased functions) cannot be inlined.

You make that sound as if "virtual function" = "aliased function" = function that has a 'problem' with aliasing. That's not what I meant by aliasing (and what the word aliasing is used in this context for generally). It's the lack of possibilities a compiler has to optimize beyond function bounderies. And that's an issue for any function call (except inlined functions). So while it's right that you can't inline virtual functions (how should you?!?), aliasing might be a problem, be it one that's solved by your compiler better than by your suggestions.

So, all in all, my advice is: don't use inline (or register, or auto, or goto). Unless you want to save yourself a .cpp file for a one-line-function whose definition is unlikely to change like
1
2
3
4
std::ostream& operator<<(std::ostream& out, const C& c)
{
  return c.print(out);
}
Topic archived. No new replies allowed.