What the inline function actually do? [duplicate] - c++

This question already has answers here:
When should I write the keyword 'inline' for a function/method?
(16 answers)
Closed 8 years ago.
I was searching the internet a few topics related to inline functions, but none of them took my doubts.
So far I know the inline function works the same way that a method or a block, but recently saw the following response:
By declaring a function inline you tell the compiler to replace the
complete code of that function directly into the place from where it
was called. This is a rather advanced feature that requires
understanding of lower-level programming.
So that means that in normal functions: I was at a point A and wanted to go to point B for that I get out of A and go to B, right?
Have inline functions works in this way: I was at point A and would like to go to point B for that point B comes up to point A?
What I said above is correct?

Ideally, with the inline keyword, the compiler pastes the contents of the inlined function at the point where the function is called.
Given:
void Print(void)
{
cout << "Hello World!\n";
}
int main(void)
{
Print();
return 0;
}
The compiler would emit an assembly instruction to call the Print function inside the main function.
When declaring the Print function as inline, the compiler would generate the conceptual main() function below:
int main(void)
{
// Substitute content of Print function because it's declared as inline
cout << "Hello World!\n";
return 0;
}
Remember that the inline keyword is a suggestion to the compiler and the compiler can ignore it. The compiler may already inline small functions without using the inline keyword.
Long ago, the inline keyword was used to force compilers to paste code where the function was invoked. This technique was used to eliminate function call overhead. This was in the times when compilers were less intelligent about optimizing.

The quote should read "replace the call" ... "place the complete code". The ideal behind an inline function is similar to a macro; in every place in the source code that calls the inline function, instead of calling the inline function, the call is replaced with the complete code from the inline function, and no call is made. This could generate a lot of duplicate code, but should result in faster execution, unless the increase in code size causes issues with cache. In some cases, a compiler may ignore the inline option and use a normal call.

Inline functions is a good tool when you want to save running time because when you call this kind of a function(inline) its code is then written in the call's place. Why does it save time? Because calling a regular function simply consumes more time than just pasting its functionality. Example:
inline void sayHi()
{
std::cout<<"Hi!";
}
int main()
{
sayHi(); //Calling an inline function
std::cin.get();
}
compiler pastes std::cout<<"Hi!"; instead of sayHi();
So what you said is actually correct.

Related

How does the use of `static` affect the speed of my code?

I was solving an exercise online, and at one point i needed to delete the "" from a the beginning and end of a string. This was my code:
void static inline process_value(std::string &value) {
if (value.back() !='>') {
value = value.substr(1, value.size()-2);
}
}
Called from this benchmark loop:
static void UsingStatic(benchmark::State& state) {
// Code inside this loop is measured repeatedly
for (auto _ : state) {
std::string valor("\"Hola\"");
process_valueS(valor);
// Make sure the variable is not optimized away by compiler
benchmark::DoNotOptimize(valor);
}
}
Just because of curiosity I did a benchmark.
Compiler: Clang-9.0
std: c++20
optim: O3
STL: libstdc++(GNU)
While I was at it I decided to remove static from process_value, making void inline process_value that was otherwise the same. To my surprise it was slower.
I thought that static only meant that the function was just for a file. But here it says that " 'static' means that the function should be inlined by the compiler if possible". But in that case when i removed static I think that the result should not have changed. Now I'm am confused, what other things does static do other than delimiting the function to a single .cpp, how does that affect performance?
The disassembly on QuickBench shows that the NoUsingStatic loop actually calls process_value instead of inlining it, despite the inline keyword making it legal for the compiler to do so. But UsingStatic does inline the call to process_valueS. That difference in compiler decision-making presumably explains the difference in performance, but why would clang choose not to inline a simple function declared void inline process_value(std::string &value){ ... }?
EDIT: Beacuse the question was closed because it was not clear enough, i deleted parts that where not related to the question. But if im missing some information please tell me in the comments
Clang uses a cost based decision whether a function will be inlined or not. This cost is affected by a lot of things. It is affected by static.
Fortunately, clang has an output, where we can observe this. Check out this godbolt link:
void call();
inline void a() {
call();
}
static inline void b() {
call();
}
void foo() {
a();
b();
}
In this little example, a() and b() are the same, the only exception is that b() is static.
If you move the mouse over the calls a() or b() on godbolt (in OptViewer window), you can read:
a(): cost=0, threshold=487
b(): cost=-15000, threshold=487
(clang will inline a call, if the cost is less than the threshold.)
clang gave b() a much lower cost, because it is static. It seems that clang will only give this -15000 cost reduction for a static function only once. If b() is called several times, the cost of all b()s will be zero, except one.
Here are the numbers for your case, link:
process_value(): cost=400, threshold=325 -> it is just above the threshold, won't be inlined
process_valueS():: cost=-14600, threshold=325 -> OK to inline
So, apparently, static can have a lot of impact, if it is only called once. Which makes sense, because inlining a static function once doesn't increase code size.
Tip: if you want to force clang to inline a function, use __attribute__((always_inline)) on it.
inline is just an advise to the compiler, which may or may not really inline that your particular code.
Regarding to the static keyword, if it's applied to a global variable, then it has the file-scope (as you've mentioned) if you compile your code as a separate compilation-unit. So it's even possible to have your static global variables accessible from other files if you compile them as a single compilation unit. This means that in reality, the scope of the global static variables is not the file but the compilation unit (which may or may not be one single file).
But, since you have a global static function, not a variable, it is accessible from everywhere as a global static function.
EDIT:
As suggested by #Peter Cordes in comments below, it may be a real mess with inline and static at the same time, so the official doc ( https://en.cppreference.com/w/cpp/language/inline ) says that the redefinition of inline functions (and variables since C++17) must be non-static.

Having trouble when linking the program with undefined symbols [duplicate]

Why should i do something like this:
inline double square (double x) { return x*x;}
instead of
double square (double x) { return x*x;}
Is there a difference?
The former (using inline) allows you to put that function in a header file, where it can be included in multiple source files. Using inline makes the identifier in file scope, much like declaring it static. Without using inline, you would get a multiple symbol definition error from the linker.
Of course, this is in addition to the hint to the compiler that the function should be compiled inline into where it is used (avoiding a function call overhead). The compiler is not required to act upon the inline hint.
On a modern compiler there is likely not much difference. It may be inlined without the inline and it may not be inlined with the inline.
Yes there is a difference. https://isocpp.org/wiki/faq/inline-functions.
When you specify that a function is inline you are causing the compiler to put the code of the method in where ever it is being called.
void myfunc() {
square(2);
}
is identical to
void myfunc() {
2 * 2;
}
Calling a function is good for code clarity, but when that function is called the local state has to be pushed to the stack, a new local state is setup for the method, and when it is done the previous state needs to be popped. That is a lot of overhead.
Now if you up your optimization level, the compiler will make decisions like unrolling loops or inlining functions. The compiler is still free to ignore the inline statement.
From Wikipedia: Inline function is a function upon which the compiler has been requested to perform inline expansion. In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined. Compilers are not obligated to respect this request.
http://en.wikipedia.org/wiki/Inline_function
inline works well with the concept of procedural abstraction:
inline double square (double x) { return x*x;}
int squareTwice(double x) {
double first = square(x);
double second = square(x);
return first * second;
}
The above is fundamentally similar to the following:
int squareTwice(double x) {
double first = x*x;
double second = x*x;
return first * second;
}
This happens because when the compiler inline-expands a function call, the function's code gets inserted into the caller's code stream; therefore, it may be easier to procedurally abstract the second example to the first example.
Procedural abstraction makes it possible to break up a routine into smaller subroutines that are much easier to read (although this can be a style choice).
The inline function, if the compiler complies, will include the inline function in the code in which it was called as if no function was called (as though you had put the logic in the calling function) and avoid the function call overhead.

C++ inline function, parameter passed by value

well last time I checked an inline function is a function whose body is substituted directly in every point in the program where the function is called.
So when I do this :
#include <iostream>
inline void increment(int n) { n = n + 1; }`
int main() {
int n = 0;
increment(n);
std::cout << "Result " << n;
}
I should have : Result 1.
Instead, I get 0.
So how does an inline function work ?
'inline' doesn't replace the text with the function body the way a macro does. It replaces the function call with the EQUIVALENT generated code, so that functionaly it's no different than if it weren't inline.
This is not a problem with it being inline but with the method signature being wrong:
inline void increment(int& n) {
++n;
}
You're asking for a copy, you're getting one. Instead ask for a reference. Don't confuse inline functions with macros, they are not the same. In fact, declaring things inline is usually counter-productive as the compiler will make this call for you depending on your optimization settings.
There are two things you should consider while inlining.
1) Inline is just a request to compiler rather than command to replace the function call with its body so as to avoid overhead related to function calls.
2) You should always inline the functions which are pretty small like getters/setters. Because inlining large functions OR recursive functions lead to code bloat which defeats the purpose of inlining.
Also inline functions have static linkage.

How will this code compile

Suppose we have below code:
inline void DoSome()
{
cout << "do some" << endl;
}
int main()
{
void (*pDoSome)() = DoSome;
DoSome(); // one
pDoSome(); // two
}
For above code we have three possible scenarios:
one will be inlined, two won't
one and two will be inlined
one and two won't be inlined (because we took the address of function)
Now I want know which of the above scenarios is true?
inline is a hint to the compiler, but it is not an obligation. It is up to the compiler to decide if a function declared as inline will actually be inlined and thus any of the two calls may or may not be inlined.
All scenarios are possible, because the compiler may optimise as it wants. The only option to see what happened is to look in the assembler output.

c++ inline function?

Why should i do something like this:
inline double square (double x) { return x*x;}
instead of
double square (double x) { return x*x;}
Is there a difference?
The former (using inline) allows you to put that function in a header file, where it can be included in multiple source files. Using inline makes the identifier in file scope, much like declaring it static. Without using inline, you would get a multiple symbol definition error from the linker.
Of course, this is in addition to the hint to the compiler that the function should be compiled inline into where it is used (avoiding a function call overhead). The compiler is not required to act upon the inline hint.
On a modern compiler there is likely not much difference. It may be inlined without the inline and it may not be inlined with the inline.
Yes there is a difference. https://isocpp.org/wiki/faq/inline-functions.
When you specify that a function is inline you are causing the compiler to put the code of the method in where ever it is being called.
void myfunc() {
square(2);
}
is identical to
void myfunc() {
2 * 2;
}
Calling a function is good for code clarity, but when that function is called the local state has to be pushed to the stack, a new local state is setup for the method, and when it is done the previous state needs to be popped. That is a lot of overhead.
Now if you up your optimization level, the compiler will make decisions like unrolling loops or inlining functions. The compiler is still free to ignore the inline statement.
From Wikipedia: Inline function is a function upon which the compiler has been requested to perform inline expansion. In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined. Compilers are not obligated to respect this request.
http://en.wikipedia.org/wiki/Inline_function
inline works well with the concept of procedural abstraction:
inline double square (double x) { return x*x;}
int squareTwice(double x) {
double first = square(x);
double second = square(x);
return first * second;
}
The above is fundamentally similar to the following:
int squareTwice(double x) {
double first = x*x;
double second = x*x;
return first * second;
}
This happens because when the compiler inline-expands a function call, the function's code gets inserted into the caller's code stream; therefore, it may be easier to procedurally abstract the second example to the first example.
Procedural abstraction makes it possible to break up a routine into smaller subroutines that are much easier to read (although this can be a style choice).
The inline function, if the compiler complies, will include the inline function in the code in which it was called as if no function was called (as though you had put the logic in the calling function) and avoid the function call overhead.