Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two questions about inline functions in C++

Tags:

c++

inline

I have question when I compile an inline function in C++.

Can a recursive function work with inline. If yes then please describe how.

I am sure about loop can't work with it but I have read somewhere recursive would work, If we pass constant values.

My friend send me some inline recursive function as constant parameter and told me that would be work but that not work on my laptop, no error at compile time but at run time display nothing and I have to terminate it by force break.

inline f(int n) {
    if(n<=1)
        return 1;
    else {
        n=n*f(n-1);
        return n;
    }
}

how does this work?

I am using turbo 3.2


Also, if an inline function code is too large then, can the compiler change it automatically in normal function?

thanks

like image 680
userBI Avatar asked Feb 26 '23 10:02

userBI


2 Answers

This particular function definitely can be inlined. That is because the compiler can figure out that this particular form of recursion (tail-recursion) can be trivially turned into a normal loop. And with a normal loop it has no problem inlining it at all.

Not only can the compiler inline it, it can even calculate the result for a compile-time constant without generating any code for the function.

With GCC 4.4

int fac = f(10); 

produced this instruction:

movl    $3628800, 4(%esp)

You can easily verify when checking assembly output, that the function is indeed inlined for input that is not known at compile-time.

like image 105
UncleBens Avatar answered Mar 08 '23 17:03

UncleBens


I suppose your friend was trying to say that if given a constant, the compiler could calculate the result entirely at compile time and just inline the answer at the call site. c++0x actually has a mechanism for this called constexpr, but there are limits to how complex the code is allowed to be. But even with the current version of c++, it is possible. It depends entirely on the compiler.

This function may be a good candidate given that it clearly only references the parameter to calculate the result. Some compilers even have non-portable attributes to help the compiler decide this. For example, gcc has pure and const attributes (listed on that page I just linked) that inform the compiler that this code only operates on the parameters and has no side effects, making it more likely to be calculated at compile time.

Even without this, it will still compile! The reason why is that the compiler is allowed to not inline a function if it decides. Think of the inline keyword more of a suggestion than an instruction.

Assuming that the compiler doesn't calculate the whole thing at compile time, inlining is not completely possible without other optimizations applied (see EDIT below) since it must have an actual function to call. However, it may get partially inlined. In that case the compiler will inline the initial call, but also emit a regular version of the function which will get called during recursion.

As for your second question, yes, size is one of the factors that compilers use to decide if it is appropriate to inline something.

If running this code on your laptop takes a very long time, then it is possible that you just gave it very large values and it is simply taking a long time to calculate the answer... The code look ok, but keep in mind that values above 13! are going to overflow a 32-bit int. What value did you attempt to pass?

The only way to know what actually happens is to compile it an look at the assembly generated.

PS: you may want to look into a more modern compiler if you are concerned with optimizations. For windows there is MingW and free versions of Visual C++. For *NIX there is of course g++.

EDIT: There is also a thing called Tail Recursion Optimization which allows compilers to convert certain types of recursive algorithms to iterative, making them better candidates for inlining. (In addition to making them more stack space efficient).

like image 27
Evan Teran Avatar answered Mar 08 '23 18:03

Evan Teran