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
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.
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).
Recursive function can be inlined to certain limited depth of recursion. Some compilers have an option that lets you to specify how deep you want to go when inlining recursive functions. Basically, the compiler "flattens" several nested levels of recursion. If the execution reaches the end of "flattened" code, the code calls itself in usual recursive fashion and so on. Of course, if the depth of recursion is a run-time value, the compiler has to check the corresponding condition every time before executing each original recursive step inside the "flattened" code. In other words, there's nothing too unusual about inlining a recursive function. It is like unrolling a loop. There's no requirement for the parameters to be constant.
What you mean by "I am sure about loop can't work" is not clear. It doesn't seem to make much sense. Functions with a loop can be easily inlined and there's nothing strange about it.
What are you trying to say about your example that "displays nothing" is not clear either. There is nothing in the code that would "display" anything. No wonder it "displays nothing". On top of that, you posted invalid code. C++ language does not allow function declarations without an explicit return type.
As for your last question, yes, the compiler is completely free to implement an inline function as "normal" function. It has nothing to do with function being "too large" though. It has everything to do with more-or-less complex heuristic criteria used by that specific compiler to make the decision about inlining a function. It can take the size into account. It can take other things into account.
You can inline recursive functions. The compiler normally unrolls them to a certain depth- in VS you can even have a pragma for this, and the compiler can also do partial inlining. It essentially converts it into loops. Also, as #Evan Teran said, the compiler is not forced to inline a function that you suggest at all. It might totally ignore you and that's perfectly valid.
The problem with the code is not in that inline function. The constantness or not of the argument is pretty irrelevant, I'm sure.
Also, seriously, get a new compiler. There's modern free compilers for whatever OS your laptop runs.
One thing to keep in mind - according to the standard, inline is a suggestion, not an absolute guarantee. In the case of a recursive function, the compiler would not always be able to compute the recursion limit - modern compilers are getting extremely smart, a previous response shows the compiler evaluating a constant inline and simply generating the result, but consider
bigint fac = factorialOf(userInput)
there's no way the compiler can figure that one out........
As a side note, most compilers tend to ignore inlines in debug builds unless specifically instructed not to do so - makes debugging easier
Tail recursions can be converted to loops as long as the compiler can satisfactorily rearrange the internal representation to get the recursion conditional test at the end. In this case it can do the code generation to re-express the recursive function as a simple loop
As far as issues like tail recursion rewrites, partial expansions of recursive functions, etc, these are usually controlled by the optimization switches - all modern compilers are capable of pretty signficant optimization, but sometimes things do go wrong.
Remember that the inline key word merely sends a request, not a command to the compiler. The compliler may ignore yhis request if the function definition is too long or too complicated and compile the function as normal function.
in some of the cases where inline functions may not work are
For functions returning values, if a loop, a switch or a goto exists.
For functions not returning values, if a return statement exists.
If function contains static variables.
If in line functions are recursive.
hence in C++ inline recursive functions may not work.
Related
This question already has answers here:
When to use the inline function and when not to use it?
(14 answers)
Closed 7 years ago.
If a function is only used in one place and some profiling shows that it's not being inlined, will there always be a performance advantage in forcing the compiler to inline it?
Obviously "profile and see" (and in the case of the function in question, it did prove to be a small perf boost). I'm mostly asking out of curiosity -- are there any performance disadvantages to this with a reasonably smart compiler?
No, there are notable exceptions. Take this code for example:
void do_something_often(void) {
x++;
if (x == 100000000) {
do_a_lot_of_work();
}
}
Let's say do_something_often() is called very often and from many places. do_a_lot_of_work() is called very rarely (one out of every one hundred million calls). Inlining do_a_lot_of_work() into do_something_often() doesn't gain you anything. Since do_something_often() does almost nothing, it would be much better if it got inlined into the functions that call it, and in the rare case that they need to call do_a_lot_of_work(), they call it out of line. In that way, they are saving a function call almost every time, and saving code bloat at every call site.
One legitimate case where it makes sense not to inline a function, even if it's only called from a single location, is if the call to the function is rare and almost always skipped. Keeping the instructions before the function call and the instructions after the function call closely together in memory may allow those instructions to be kept in the processor cache, when that would be impossible if those blocks of instructions were separated in memory.
It would still be possible for the compiler to compile the function call as if using goto, avoiding having to keep track of a return address, but if the compiler has already determined that the function call is rare, then it makes sense to not pay as much time optimising that call.
You can't "force" the compiler to inline it, unless you are considering some implementation-specific tools that you have not mentioned, so the question is entirely moot.
If your compiler is already not doing so then it has a reason.
If the function is called only once, there should be no performance disadvantages in inlining it. However, that does not mean you should blindly inline all functions. For example, if the code in question is Linux kernel code and you're using the BUG_ON or WARN_ON statement to print a stack trace, you don't get the full stack trace which includes the inline function. Instead, the stack trace contains only the name of the calling function.
And, as the other answer explained, the "inline" doesn't actually force the compiler to inline the function, it just is a hint to the compiler. However, there is actually an attribute __attribute__((always_inline)) in GCC which should force the compiler to inline the function.
Make sure that the function definition is not exported. If it is, it obviously needs to be compiled, and that means that if your function is big probably the call will not be inlined. (Remember, it's the call that gets inlined, not the function. A function might get inlined in one place and called in another, etc.)
So even if you know that the function is called only from one place, the compiler might not. Make sure to hide the definition of your function to the other object files, for example by defining it in the anonymous namespace.
That being said, even if it is called from only one place, it does not mean that it is always a good idea to inline it. If your function is called rarely, it might waste a lot of memory in the CPU cache.
Depending on how you wrote your function.
In some cases, yes!
void doSomething(int *src, int *dst,
const int loopCountInner, const int loopCountOuter)
{
int i, j;
for(i=0; i<loopCounterOuter; i++){
for(j=0; j<loopCounterInner; j++){
*dst = someCalculations(*src);
src++;
dst++
}
}
}
In this example, if this function is compiled as non-inlined, then compiler basically has no knowledge about the trip count of the two loops. This is a big deal for implementations that rely strongly on compile-time optimizations.
I came across a even worse case: compiler assumes loopCounterInner to be a large value and optimized for that case, but loopCounterInner is actually 3 or 5 so the best choice is to fully unroll the inner loop!
For C++ probably the best way to do it is to make them template variables, but for C, the only way to generate differently optimized code for different use cases is to inline the function.
No, if the code is a rarely used function then keeping it off the 'hot path' will be beneficial. An inline function will use up cache space [instruction cache] whether or not the code is actually used. Tools like LTCG combined with Profile Guided optimisation (in the MSFT world, not sure about Linux) go to great pains to keep rarely used code off the hot path and this can make a significant difference
We have a macro for signalling errors in a common utilities library that goes like this:
#define OurMacro( condition ) \
if( condition ) { \
} else { \
CallExternalFunctionThatWillThrowAnException( parametersListHere ); \
} \
What I refer to as parametersListHere is a comma-separated list of constants and macros that is populated by the compiler at each macro expansion.
That function call always resolves into a call - the function implementation is not exposed to the compiler. The function has six parameters and in debug configuration all of them have meaningful values, while in release configuration only two have meaningful values and others are passed the same default values.
Normally the condition will hold true, so I don't care how fast the invokation is, I only care about the code bloat. Calling that function with 6 parameters requires seven x86 instruction (6 pushes and one call), and clearly 4 of those pushes can be avoided if the function signature is changed to have two parameters only - this can be done by introducing an intermediate "gate" function implemented in such way its implementation is not visible to the compiler.
I need to estimate whether I should insist on that change. So far the primary improvement I expect is that reducing the number of parameters will drop 4 instructions on each invokation which means that the code surrounding the macro expansion will become smaller and the compiler will inline it more likely and optimize the emitted code further.
How can I estimate that without actually trying and recompiling all our code and carefully analyzing the emitted code? Every time I read about inline there's a statement that the compiler decides whether to inline the function.
Can I see some exact set of rules of how the function internals influence compiler decision on inlining?
GCC has a fairly large set of options that expose how their process works, documented here. It's of course not exact, given that it will be tweaked over time and it's CPU-dependent.
The first rule is "their body is smaller than expected function call code".
A second rule is "static functions called once".
There are also parameters affecting the inling process, e.g. max-inline-insns-single. An insn is a pseudo-instruction in the GCC compiler, and is used here as a measure of function complexity. The documentation of parameter max-inline-insns-auto makes it clear that manually declaring a function inline might cause it to be considered for inlining even if it is too big for automatic inlining.
Inlining isn't a all-or-nothing process, since there's a -fpartial-inlining flag.
Of course, you can't consider inlining in isolation. Common Subexpression Elimination (CSE) makes code simpler. It's an optimization pass that may make a function small enough to be inlined. After inlining, new common subexpressions may be discovered so the CSE pass should be run again, which in turn might trigger further inlining. And CSE isn't the only optimization that needs rerunning.
The rules on what functions get inlined and under what conditions (e.g. selected optimization level) are specific to each compiler, so I suggest you check your compiler's documentation. However, a function that just forwards to another function (as you propose) should be a good candidate for inlining by any compiler that supports it.
Some compilers have a mechanism whereby you can flag that you really want a function to be inlined, e.g. MSVC++ has __forceinline.
If you are using Visual C++, you can use __forceinline to force the compiler to inline a function.
Inline functions are just a request to compilers that insert the complete body of the inline function in every place in the code where that function is used.
But how the compiler decides whether it should insert it or not? Which algorithm/mechanism it uses to decide?
Thanks,
Naveen
Some common aspects:
Compiler option (debug builds usually don't inline, and most compilers have options to override the inline declaration to try to inline all, or none)
suitable calling convention (e.g. varargs functions usually aren't inlined)
suitable for inlining: depends on size of the function, call frequency of the function, gains through inlining, and optimization settings (speed vs. code size). Often, tiny functions have the most benefits, but a huge function may be inlined if it is called just once
inline call depth and recursion settings
The 3rd is probably the core of your question, but that's really "compiler specific heuristics" - you need to check the compiler docs, but usually they won't give much guarantees. MSDN has some (limited) information for MSVC.
Beyond trivialities (e.g. simple getters and very primitive functions), inlining as such isn't very helpful anymore. The cost of the call instruction has gone down, and branch prediction has greatly improved.
The great opportunity for inlining is removing code paths that the compiler knows won't be taken - as an extreme example:
inline int Foo(bool refresh = false)
{
if (refresh)
{
// ...extensive code to update m_foo
}
return m_foo;
}
A good compiler would inline Foo(false), but not Foo(true).
With Link Time Code Generation, Foo could reside in a .cpp (without a inline declararion), and Foo(false) would still be inlined, so again inline has only marginal effects here.
To summarize: There are few scenarios where you should attempt to take manual control of inlining by placing (or omitting) inline statements.
The following is in the FAQ for the Sun Studio 11 compiler:
The compiler generates an inline function as an ordinary callable function (out of line) when any of the following is true:
You compile with +d.
You compile with -g.
The function's address is needed (as with a virtual function).
The function contains control structures the compiler can't generate inline.
The function is too complex.
According to the response to this post by 'clamage45' the "control structures that the compiler can't generate inline" are:
the function contains forbidden constructs, like loop, switch, or goto
Another list can be found here. As most other answers have specified the heuristics are going to be 100% compiler specific, from what I've read I think to ensure that a function is actually inlined you need to avoid:
local static variables
loop constructs
switch statements
try/catch
goto
recursion
and of course too complex (whatever that means)
All I know about inline functions (and a lot of other c++ stuff) is here.
Also, if you're focusing on the heuristics of each compiler to decide wether or not inlie a function, that's implementation dependant and you should look at each compiler's documentation. Keep in mind that the heuristic could also change depending on the level of optimitation.
I'm pretty sure most compilers decide based on the length of the function (when compiled) in bytes and how often it is used vs the optimization type (speed vs size).
I know only couple criteria:
If inline meets recursion - inline will be ignored.
switch/while/for in most cases cause compiler to ignore inline
It depends on the compiler. Here's (the first part of) what the GCC manual says:
-finline-limit=n
By default, GCC limits the size of functions that can be inlined.
This flag allows the control of this limit for functions that are
explicitly marked as inline (i.e., marked with the inline keyword
or defined within the class definition in c++). n is the size of
functions that can be inlined in number of pseudo instructions (not
counting parameter handling). The default value of n is 600.
Increasing this value can result in more inlined code at the cost
of compilation time and memory consumption. Decreasing usually
makes the compilation faster and less code will be inlined (which
presumably means slower programs). This option is particularly
useful for programs that use inlining heavily such as those based
on recursive templates with C++.
Inlining is actually controlled by a number of parameters, which
may be specified individually by using --param name=value. The
-finline-limit=n option sets some of these parameters as follows:
#item max-inline-insns-single
is set to I/2.
#item max-inline-insns-auto
is set to I/2.
#item min-inline-insns
is set to 130 or I/4, whichever is smaller.
#item max-inline-insns-rtl
is set to I.
See below for a documentation of the individual parameters
controlling inlining.
Note: pseudo instruction represents, in this particular context, an
abstract measurement of function's size. In no way, it represents
a count of assembly instructions and as such its exact meaning
might change from one release to an another.
it inserts if you write "inline" to beginning of the function?
I have a method like the one shown below.
Will the for loop always make the compiler for go the "inline request" ?
inline void getImsiGsmMapFrmImsi
(
const string& imsiForUEDir,
struct ImsiGsmMap& imsiGsmMap
)
{
for (int i = 0 ; (unsigned)i < imsiForUEDir.length() - 1 ; i++)
{
imsiGsmMap.value[i] = imsiForUEDir[i] - '0' ;
}
imsiGsmMap.length = imsiForUEDir.length() - 1 ;
}
You can specify "inline" and the compiler can ignore it if it feels like that.
Simply, no.
"inline" is just a hint to the compiler.
There are ways to force a compiler to inline something, but these ways are compiler-specific. Your code looks mobile to me, so here's some ways on some C++ compilers used on various mobile phone platforms:
Windows CE/ Windows Mobile VC++ ARM compiler uses the __forceinline keyword instead of the hint 'inline'.
A better compiler (i.e. makes faster output) for Windows CE/ Windows Mobile is cegcc, which uses the very latest GCC 4.4. In GCC, you write __attribute__((always_inline)) after the function name and before the body.
The bigger thing is if it's a good idea to inline this loop. I program mobile phones for a living, and they don't have much CPU budget generally. But I'd be really surprised if this loop is a bottleneck. Strip your program of all the 'inline' decorations and when you're approaching shipping, if the program is slow, profile it!
Some compilers allow 'profile guided optimisation' where they can make an instrumented binary that you run in a realistic way, and then they use the data so gathered to make a production binary where they make informed decisions about code speed vs code size in the various parts of your program to give the very best mix of both.
"No inlining for functions with loops" is probably a bit of some inline heuristic from some particular compiler. It doesn't apply universally.
Every compiler uses some heuristics to determine whether the function should be inlined or not, but normally every compiler uses its own ones. So, to say that a loop will have some universal effect on inlining is not correct. It won't. There's absolutely nothing in your function that would somehow fundamentally preclude inlining. Most modern compilers can easily inline this function, if they deem it reasonable or if you force them to do it.
Yes, some compilers offer non-standard declaration specifiers (or compiler options) that will actually force the inlining, i.e. override the heuristic analysis, except for a number of situation when the inlining is truly beyond the capabilities of the compiler. For example, many modern C/C++ compilers normally can't inline functions with variable number of parameters (variadic functions).
It also commonly believed that recursive function can't be inlined. In reality, in many compilers recursive functions can be inlined to certain fixed recursion depth, thus "compressing" the recursion.
I wonder if the inline keyword is even necessary anymore. Don't modern compilers mostly just ignore it and do whatever they think is best, anyway?
Most likely compilers will not inline a function with a loop, since what would be the point? If the code is looping, generally the cost of a function call will be unmeasurable noise compared to the looping.
But if a compiler wants to inline it (maybe the compiler is sophisticated enough to determine the loop bounds and can even unroll the loop), it's certainly allowed to.
But I wouldn't bet on it.
To summarize a previous answer I gave to this, the things you should watch out for when choosing a function for inlining are:
* local static variables
* loop constructs
* switch statements
* try/catch
* goto
* recursion
* and of course too much complexity (whatever that means)
Having said that as the other answers here point out, it's basically unspecified if the compiler inlines the function or not. 7.1.2/2 has:
A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.
An interesting detail on this, is that the compiler would normally label the kind of behaviour that's involved here. For example: "it is unspecified" or "the behaviour is undefined" etc.
While it would be very convenient to use inline functions at some situations,
Are there any drawbacks with inline functions?
Conclusion:
Apparently, There is nothing wrong with using inline functions.
But it is worth noting the following points!
Overuse of inlining can actually make programs slower. Depending on a function's size, inlining it can cause the code size to increase or decrease. Inlining a very small accessor function will usually decrease code size while inlining a very large function can dramatically increase code size. On modern processors smaller code usually runs faster due to better use of the instruction cache. - Google Guidelines
The speed benefits of inline functions tend to diminish as the function grows in size. At some point the overhead of the function call becomes small compared to the execution of the function body, and the benefit is lost - Source
There are few situations where an inline function may not work:
For a function returning values; if a return statement exists.
For a function not returning any values; if a loop, switch or goto statement exists.
If a function is recursive. -Source
The __inline keyword causes a function to be inlined only if you specify the optimize option. If optimize is specified, whether or not __inline is honored depends on the setting of the inline optimizer option. By default, the inline option is in effect whenever the optimizer is run. If you specify optimize , you must also specify the noinline option if you want the __inline keyword to be ignored. -Source
It worth pointing out that the inline keyword is actually just a hint to the compiler. The compiler may ignore the inline and simply generate code for the function someplace.
The main drawback to inline functions is that it can increase the size of your executable (depending on the number of instantiations). This can be a problem on some platforms (eg. embedded systems), especially if the function itself is recursive.
I'd also recommend making inline'd functions very small - The speed benefits of inline functions tend to diminish as the function grows in size. At some point the overhead of the function call becomes small compared to the execution of the function body, and the benefit is lost.
It could increase the size of the
executable, and I don't think
compilers will always actually make
them inline even though you used the
inline keyword. (Or is it the other
way around, like what Vaibhav
said?...)
I think it's usually OK if the
function has only 1 or 2 statements.
Edit: Here's what the linux CodingStyle document says about it:
Chapter 15: The inline disease
There appears to be a common
misperception that gcc has a magic
"make me faster" speedup option called
"inline". While the use of inlines can
be appropriate (for example as a means
of replacing macros, see Chapter 12),
it very often is not. Abundant use of
the inline keyword leads to a much
bigger kernel, which in turn slows the
system as a whole down, due to a
bigger icache footprint for the CPU
and simply because there is less
memory available for the pagecache.
Just think about it; a pagecache miss
causes a disk seek, which easily takes
5 miliseconds. There are a LOT of cpu
cycles that can go into these 5
miliseconds.
A reasonable rule of thumb is to not
put inline at functions that have more
than 3 lines of code in them. An
exception to this rule are the cases
where a parameter is known to be a
compiletime constant, and as a result
of this constantness you know the
compiler will be able to optimize most
of your function away at compile time.
For a good example of this later case,
see the kmalloc() inline function.
Often people argue that adding inline
to functions that are static and used
only once is always a win since there
is no space tradeoff. While this is
technically correct, gcc is capable of
inlining these automatically without
help, and the maintenance issue of
removing the inline when a second user
appears outweighs the potential value
of the hint that tells gcc to do
something it would have done anyway.
There is a problem with inline - once you defined a function in a header file (which implies inline, either explicit or implicit by defining a body of a member function inside class) there is no simple way to change it without forcing your users to recompile (as opposed to relink). Often this causes problems, especially if the function in question is defined in a library and header is part of its interface.
I agree with the other posts:
inline may be superfluous because the compiler will do it
inline may bloat your code
A third point is it may force you to expose implementation details in your headers, .e.g.,
class OtherObject;
class Object {
public:
void someFunc(OtherObject& otherObj) {
otherObj.doIt(); // Yikes requires OtherObj declaration!
}
};
Without the inline a forward declaration of OtherObject was all you needed. With the inline your
header needs the definition for OtherObject.
As others have mentioned, the inline keyword is only a hint to the compiler. In actual fact, most modern compilers will completely ignore this hint. The compiler has its own heuristics to decide whether to inline a function, and quite frankly doesn't want your advice, thank you very much.
If you really, really want to make something inline, if you've actually profiled it and looked at the disassembly to ensure that overriding the compiler heuristic actually makes sense, then it is possible:
In VC++, use the __forceinline keyword
In GCC, use __attribute__((always_inline))
The inline keyword does have a second, valid purpose however - declaring functions in header files but not inside a class definition. The inline keyword is needed to tell the compiler not to generate multiple definitions of the function.
I doubt it. Even the compiler automatically inlines some functions for optimization.
I don't know if my answer's related to the question but:
Be very careful about inline virtual methods! Some buggy compilers (previous versions of Visual C++ for example) would generate inline code for virtual methods where the standard behaviour was to do nothing but go down the inheritance tree and call the appropriate method.
You should also note that the inline keyword is only a request. The compiler may choose not to inline it, likewise the compiler may choose to make a function inline that you did not define as inline if it thinks the speed/size tradeoff is worth it.
This decision is generaly made based on a number of things, such as the setting between optimise for speed(avoids the function call) and optimise for size (inlining can cause code bloat, so isn't great for large repeatedly used functions).
with the VC++ compiler you can overide this decision by using __forceinline
SO in general:
Use inline if you really want to have a function in a header, but elsewhere theres little point because if your going to gain anything from it, a good compiler will be making it inline for you anyway.
Inlining larger functions can make the program larger, resulting in more instruction cache misses and making it slower.
Deciding when a function is small enough that inlining will increase performance is quite tricky. Google's C++ Style Guide recommends only inlining functions of 10 lines or less.
(Simplified) Example:
Imagine a simple program that just calls function "X" 5 times.
If X is small and all calls are inlined: Potentially all instructions will be prefetched into the instruction cache with a single main memory access - great!
If X is large, let's say approaching the capacity of the instruction cache:
Inlining X will potentially result in fetching instructions from memory once for each inline instance of X.
If X isn't inlined, instructions may be fetched from memory on the first call to X, but could potentially remain in the cache for subsequent calls.
Excessive inlining of functions can increase size of compiled executable which can have negative impact on cache performance, but nowadays compiler decide about function inlining on their own (depending on many criterias) and ignore inline keyword.
Among other issues with inline functions, which I've seen heavily overused (I've seen inline functions of 500 lines), what you have to be aware of are:
build instability
Changing the source of an inline function causes all the users of the header to recompile
#includes leak into the client. This can be very nasty if you rework an inlined function and remove a no-longer used header which some client has relied on.
executable size
Every time an inline is inlined instead of a call instruction the compiler has to generate the whole code of the inline. This is OK if the code of the function is short (one or two lines), not so good if the function is long
Some functions can produce a lot more code than at first appears. I case in point is a 'trivial' destructor of a class that has a lot of non-pod member variables (or two or 3 member variables with rather messy destructors). A call has to be generated for each destructor.
execution time
this is very dependent on your CPU cache and shared libraries, but locality of reference is important. If the code you might be inlining happens to be held in cpu cache in one place, a number of clients can find the code an not suffer from a cache miss and the subsequent memory fetch (and worse, should it happen, a disk fetch). Sadly this is one of those cases where you really need to do performance analysis.
The coding standard where I work limit inline functions to simple setters/getters, and specifically say destructors should not be inline, unless you have performance measurements to show the inlining confers a noticeable advantage.
In addition to other great answers, at least once I saw a case where forced inlining actually slowed down the affected code by 1.5x. There was a nested loop inside (pretty small one) and when this function was compiled as a separate unit, compiler managed to efficiently unroll and optimize it. But when same function was inlined into much bigger outer function, compiler (MSVC 2017) failed to optimize this loop.
As other people said that inline function can create a problem if the the code is large.As each instruction is stored in a specific memory location ,so overloading of inline function make a code to take more time to get exicuted.
there are few other situations where inline may not work
does not work in case of recursive function.
It may also not work with static variable.
it also not work in case there is use of a loop,switch etc.or we can say that with multiple statements.
And the function main cannot work as inline function.