Hello,

I have a question that can be deducted from the title. When to use C++ inline functions and when not? Should I declare my constructors/destructors as inline? Should I declare functions that have at least a loop as inline? People say that declaring small functions as inline is a good idea, what does small mean? 2 lines of code? 15 Expressions? 10 Instructions? What exactly makes a function small?

I don't believe that code lines count matters in C++ since you can be really compact. I think it's rather about expressions count that makes a function big or small because no matter how compact your code is, it will still be cut in pieces when it's translated into machine code. Expressions are contained by instructions and an instruction can have more than one expression. For instance:

char a[10][10] = {0}, i = 0;
int main(){
    a[++i][i++] = 1;
    return 0;
}

Will be translated, just the main() body without return, into (ASM):

INC i
MV a[i*10][i], 1
INC i

That's why I say expression count is the one that dictates actual function size.

What do you guys think?

Thanks for the link, still, is it good to inline constructors/destructors?

Did you not read the link? It's highly situational, so one can't simply say that inline functions are good for constructors/destructors or not in a general sense. I'd personally avoid inlining all but the simplest constructors and destructors, but for the sake of simplicity I've been known to define member functions inside of the class body, which makes them implicitly inline.

I have read the topic you linked to.

Okay, I'll rephrase, is it ok to inline empty constructors/destructors? Is it ok to inline small length constructors/destructors? Is it ok to inline long length constructors/destructors?

I don't want to sound rude or ungrateful or something like that, it's just that a general question such as "Is it good to inline constructors/destructors?" can be answered with examples that illustrate when inlining is usefull and when not (apart from the general "inline only when you're sure you get more in return than you're giving = profit (duh, that doesn't help)", in fact that is the question. How can I determine when I get more in return than giving by inlining?). The topic you linked to mentioned output profiles, is there no other way? Also it doesn't say anything about constructors/destructors (yes they are usual methods, however a bit more special). It resumes to "avoid inlining" because all inlining increases coupling, however it can reduce program size by skipping some function call stepts that need to be done which goes back to the question "How can I determine a functions size?" in order to conclude that I get profit by inlining.

Okay, I'll rephrase, is it ok to inline empty constructors/destructors?

At the risk of being overly concise, yes, that's fine.

Is it ok to inline small length constructors/destructors?
Is it ok to inline long length constructors/destructors?

Now you're getting into the situational aspect. The usual recommendation for inlining is to keep it to small length functions because if it's actually inlined by the compiler, every call of that function will essentially be replaced with the body of the function. This can add up in terms of code size and ultimately increase the size of your executable file.

a general question such as "Is it good to inline constructors/destructors?" can be answered with examples that illustrate when inlining is usefull and when not

I don't think inlining is useful in practice. I never use the inline keyword explicitly and would prefer an equivalent noinline hint for functions defined inside the class definition. Pity it's not available in standard C++.

The topic you linked to mentioned output profiles, is there no other way?

The point of inlining is performance, right? So it's reasonable to assume that the only way to determine when inlining is viable is to measure performance. As the article also mentioned, programmers are notoriously bad at guessing where inlining could be beneficial.

Also it doesn't say anything about constructors/destructors (yes they are usual methods, however a bit more special).

That's largely irrelevant. The only consideration with constructors and destructors in terms of inlining, and especially with destructors, is that they're usually called implicitly. Thus it's not as simple to search or eyeball your code for instances. They're harder to guesstimate benefits of inlining, and it's more important to use a performance profiler and measure the speed changes against executable size changes.

"How can I determine a functions size?" in order to conclude that I get profit by inlining.

Define profit, some people want fast performance more and some want small size more. At what point do you consider the trade off of speed versus size beneficial? Is there actually a speed improvement or do you end up thrashing memory due to the extra size? These aren't questions that can be answered without context. That's why it's situational.

You can't simply say that a function with N instructions or less is "short" and more than that is "long", because it might apply to one program and not to another. Even compiling the same program with a different compiler can change the numbers behind the scenes and ruin your estimates. The problem here is that you're trying to oversimplify the concept of inlining to a number that can be used everywhere. If it were that simple, the general consensus wouldn't be to avoid inlining.

I find profit when I inline (or do some other optimization, doesn't only apply to inline) and get better speed and lower memory usage in return, however when a decision has to be made I'll go for speed if the memory expense isn't too costy.

I also try to keep a balance between memory usage and speed, if I have a big (in terms of memory size) application that is very fast I may cut some speed to reduce the size. And this goes back to the profit, if I have a lot of speed because I retain a lot of data in memory I may just decide to go for memory efficiency rather than speed.

That is because the "wonderful" speed I think I have may just be an illusion, if there isn't enough RAM for my app to fit, generally speaking, it will take more time to unload other processes load my app and viceversa than a smaller and a bit slower app.

If there is no way to exactly define if a function is small then the definition of a small length function is purely subjective and when one says "Small length functions should be inlined" actually said nothing. I may say a function with 100 instructions is small and someone else will disagree, however none will be right because there's nothing telling what small length functions actually are. In conclusions there is no such think as small length functions and it's just a short-hand notation used by devs that know how each other code and can say what a short function is for that particular person.

I find the counting of instructions irrelevant to actual function size, I can squeeze a handful of expressions, that can be done one at the time at machine level, into a few instructions in C++. Nevertheless saying that a function with an expression count no greater than <N> can be considered as short by a set of standards could make a reliable definition.

This article has been dead for over six months. Start a new discussion instead.