This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When to use inline function and when not to use it?
Under what conditions can (not should) a function not be inlined (C++ Only) ?
Two conditions that i know of are :
1 . If the function has a recursive call
2 . If there are static variables in the function
inline is a keyword of C++, but inlining is a generic process performed by a compiler backend, usually after instruction sequences are already generated.
A C compiler will also inline functions, and a C++ compiler will inline functions that aren't inline. A C++ compiler can also fail to inline an inline function for any arbitrary reason. The keyword actually exists to specify that a function may have multiple, identical definitions in different translation units (source files).
Static variables have no special bearing on whether something can be inlined. Perhaps some compilers have difficulty linking the resulting structure of global variable references, but that's more of a bug than a rule of thumb.
Recursive functions can be inlined, too. The recursive call should be translated to a branch. The branch could then be targeted by loop unrolling.
A function that compiles to more than a kilobyte of code will usually not be inlined. But a compiler may provide #pragma directives or platform-specific attributes to force inlining in such a case.
The biggest factor that would stop a function from being inlined is if its source isn't available to the compiler at the time of code generation. Link-time optimization opens the possibility of inlining functions that are extern and not inline but a function supplied by a DLL is certainly off limits. But then, you could still run it through a JIT style execution engine and that could inline (splice together) any random fragments it likes.
The only situation in which a function cannot be inlined is if there is no definition for the function in the compilation unit. Even that will not prevent link-time inlining by a link-time optimizer.
Note that the inline keyword is really just a hint -- a compiler may choose not to inline functions with it and choose to inline functions without it.
Related
This question already has answers here:
When should I write the keyword 'inline' for a function/method?
(16 answers)
Closed 2 years ago.
I'm learning c++ via this page.
In the page above and this page, it says that a modern compiler is smart enough to decide which side will have the better performance regarding the inlining of the function. The compiler is smarter than a human in most cases.
So, I thought that we could use the inline keyword if we want to force the compiler to treat the function as inline, but that was not the case. It says that even if the function is declared as inline, the compiler is free to (and usually does) ignore the keyword.
Does this mean that the function's inline-ness is not decided by the inline keyword, but rather the compiler has the ultimate privilege to decide it? If so, then isn't it useless for a programmer to explicitly declare a function as inline?
On the pretext on when it was defined, it seemed to be a good optimization, however it doesn't hold any value now since C++17.
What it implies now is that it can have multiple identical definitions, and needs to be defined in every translation unit that uses it.
Does it mean that the function's inline-ness is not decided by the inline keyword, but the compiler has the entire privilege to decide it?
Yes. It doesn't depend on whether you use inline or not as well. Compilers can self-identify whether to inline a function or not.
If so, then isn't it useless for a programmer to explicitly declare function as inline?
Refer to its usage mentioned above for inline functions.
Pertaining to the question title, the inline keyword is applicable to inline variables (C++ 17) as well, which allows such variables to be defined in multiple translation units, following the one definition rule. If defined more than once, the compiler merges them all into a single object in the final program.
The inline keyword has nothing to do with inlining calls to a function. All it does is allow the function (or object, as of C++17) to be defined in multiple compilation units. That is, it allows a function to be defined inline in a header where it's declared.
This may assist the compiler in being able to inline calls to a function, since the full definition of a function defined in a header is visible in multiple translation units. The inline keyword is not a requirement, or even a hint, that the compiler should inline the calls. The compiler will make that determination on its own.
There is no standard way to force the compiler to inline calls to a function, but most compilers provide an extension to do so. For example, GCC has the always_inline attribute.
I know in some cases, the explicitly defined inline function will be converted to the regular function with calling stacks by the compiler. By how do I know this is the case? (for my C++ code)
BTW, in what circumstances will the compiler transform an inline function to a regular function?
You run nm or otool on the executable, and if you see the name of the function, then it has been defined. That doesn't mean that it hasn't indeed been inlined at all (it's possible that the compiler inlines a function but also generates an independent function body because for example one assigns a function pointer to it). For that, you need to examine the actual generated assembly code.
The keyword inline does not mean that the function will be inlined (or not). It means allow for multiple definitions in different translation units of the same program. The compiler will not transform an inline into a non-inline, it will follow the rules set in the standard and (almost) orthogonally determine whether to inline or not your functions.
As of whether to determine if a function was inlined or not, the guaranteed way to do so is checking the generated object code (or assembly). Checking whether there is an out-of-line definition of the function won't help, as many compilers will generate that out-of-line definition even if the code was actually inlined.
The compiler will DEFINITELY produce a regular function if the inline function has it's address taken (that is, you are making a function pointer to it, or something similar). And of course, if the function is virtual, it also has to exist as a standalone function since a virtual function call is not always possible to inline.
Other than that, it's entirely up to the compiler - it uses all manner of heuristics, such as "How big is the function?", "how many times is it called?", "how much 'gain' is there from inlining it?". If a function is called many times, and is quite large, it is probably left as a standalone function. If the function is only called a few times, or it's tiny, then it's inlined [assuming the compiler actually CAN inline it, of course - as described above, it may not be able to]. Also, nearly all compilers need to "see" the source code of the function to inline the function, but both GCC/G++ and MSVC do have otions for "whole program optimisation" that is intended to overcome this issue.
In other words, you can only "know" by reading the resulting machine code - in some cases, there are also extended "warning" or "notes" messages that you can enable to tell the compiler to give you information about "I did not inline function Func1 because ...insert some reason here...".
This question already has answers here:
How will i know whether inline function is actually replaced at the place where it is called or not?
(10 answers)
Closed 9 years ago.
In gcc, using
-E gives the preprocessed code;
-S, the assembly code;
-c, the code compiled, but not linked.
Is there anything close to a -I, that would allow me to see whether a function has been inlined or not, i.e., to see the code expanded, as though inline functions were preporcessed macros?
If not, should I get my way through the assembly code, or are the inline applications performed later?
I think examining the assembly code is the best (and pretty much the only) way to see what's been inlined.
Bear in mind that, in certain circumstances, some inlining can take place at link time. See Can the linker inline functions?
You can use the -Winline option to see whether a function can not be inlined and it was declared as inline.
Quoted from http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options
-Winline
Warn if a function that is declared as inline cannot be inlined. Even with this option, the compiler does not warn about failures to inline functions declared in system headers.
The compiler uses a variety of heuristics to determine whether or not to inline a function. For example, the compiler takes into account the size of the function being inlined and the amount of inlining that has already been done in the current function. Therefore, seemingly insignificant changes in the source program can cause the warnings produced by -Winline to appear or disappear.
However, inline is not a command, whether inline a function or not(though declared as inline) is decided by the compiler. It may consider the size of the function being inlined and how many times inline already been done in the current function.
The best way to see whether a function has really been inlined is to check the assembly code. For example, you can use
gcc -O2 -S -c foo.c
to generate assembly code for foo.c and output assembly code file foo.s.
The issue here is that generally inlining is a link time optimaztion (when there are multiple object files) as the compiler simply doesn't see the implementation of functions in other object files, until link time.
Hence in multi object file compiles your best shot is to inspect the generated assembly, however within every single object file, the inlining is possible, assuming the function to be inlined is in the same compilation unit, however most compilers do not do inlining at this point, as it doesnt know where this function may be called from, and whether it should itself be inlined.
So in general inlining is performed on linking, however for very small functions, it can and should be done at compilation time.
Also I do believe that if you compile your code with clang/llvm, you'll get a c output file with inlining, tho I haven't tried it.
Do note that in order to get GCC to do the link time optimization (including inlining) you'll have to provide it with an argument, I think its -flto.
An alternative is to have all your inline functions visible in your all of your compilation units (e.g. In the header files), this will actually usually ensure inlining in order to avoid multiple declarations of the same function, in different object files.
Also an easy way to check the assembly for inlining is to compare the number of calls to the function in the source code to the number of calls in the assembly.
I was told long ago to make short functions/methods that are called often inline, by using the keyword inline and writing the body in the header file.
This was to optimize the code so there would be no overhead for the actual function call.
How does it look with that today? Does modern compilers (Visual Studio 2010's in this case) inline such short functions automatically or is it still "necessary" to do so yourself?
inline has always been a hint to the compiler, and these days compilers for the most part make their own decisions in this regard (see register).
In order to expand a function inline, the compiler has to have seen the definition of that function. For functions that are defined and used in only one translation unit, that's no problem: put the definition somewhere before it's used, and the compiler will decide whether to inline the function.
For functions that are used in more than one translation unit, in order for the compiler to see the definition of the function, the definition has to go in a header file. When you do that, you need to mark the function inline to tell the compiler and linker that it's okay that there's more than one definition of that function. (well, I suppose you could make the function static, but then you could end up wasting space with multiple copies)
Enable warning C4710, this will warn you if a function which you define as inline is not inlined by the compiler.
Enable warning C4711, this will warn you if the compiler inlines a function not designated for inlining.
The combination of these two warnings will give you a better understanding of what the compiler is actually doing with your code and possibly whether it is worth designating inline functions manually or not.
Generally speaking, the inline keyword is used more now to allow you to "violate" the one definition rule when you define a function in a header than to give the compiler a hint about inlining. Many compilers are getting really good at deciding when to inline functions or not, as long as the function body is visible at th4e point of call.
Of course if you define the function only in a source file non-inline, the compiler will be able to inline it in that one source file but not in any other translation unit.
Inlining may be done by a compiler in the following situations:
You marked the function as inline and
it's defined in a current translation unit or in file that it's included in it;
compiler decides that it's worth doing so. According to the MSDN
The inline keyword tells the compiler that inline expansion is preferred.
The compiler treats the inline expansion options and keywords as suggestions.
You used the __forceinline keyword (or __ attribute __((always_inline)) in gcc). This will make compiler to skip some checks and do the inlining for you.
The __forceinline keyword overrides the cost/benefit analysis and relies on the judgment of the programmer instead.
Microsoft compiler can also perform cross module inlining if you have turned on link time code generation by passing /GL flag to the compiler or /LTCG to the linker. It's quite clever in making such optimizations: try to examine the assembly code of modules compiled with /LTCG.
Please note, that inlining will never happen if your function is:
a recursive one;
called through a pointer to it.
Yes, modern compilers will (depending on various configuration options) automatically choose to inline functions, even if they're in the source (not header) file. Using the inline directive can give a hint.
Aside from your main point (what amount of placing inline instructions in code is useful as of compilers today), keep in mind that inline functions are just a hint to the compiler, and are not necessarily being compiled as inline.
In short, yes, compilers will decide whether or not your function becomes inline. You can check this question:
Does the compiler decide when to inline my functions (in C++)?
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Inline functions in C++
Modern compilers are better than programmers at deciding what should be inlined and what should not. Just like, register, shouldn't inlining functions be a job for the compiler only, and be considered premature optimization ?
inline has a double meaning that some are unaware of - it allows a function to be defined in more than one translation unit (i.e. if you define an unbound function in a header and include it from within various translation units, you are forced to declare it inline or the linker would complain about doubly defined symbols).
The second meaning is a hint to the compiler that this function may profit from inlining its machine code at the caller site. You're right, modern compilers/optimizers should be able to figure this out on his own.
My advice is to use inline only when it is needed (first case) and never to pass an optimization hint to the compiler. This way, this crazy double meaning is resolved in your source code.
inline is only tangentially related to optimization.
You should choose to apply inline to a function if you need the exceptions to the one definition rule that it gives you, and leave it out if you don't. Most of the time you can rely on the compiler to perform the appropriate optimizations independent of whether a function is declared inline or not.
Check out this answer: Inlining this function or not?
Essentially, yes, inlining is a task of the compiler at this point. Inlining was initially created to indicate to the compiler that it should try. The keyword is indicate - The compiler has the choice as to whether or not it inlines the function or not.