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.
Related
I know in advance that, when writing a program in C or C++, even if I declare a function as "inline" the compiler is free to ignore this and decide not to expand it at each (or any) call.
Is the opposite true as well? That is, can a compiler automatically inline a very short function that wasn't defined as inline if the compiler believes doing so will lead to a performance gain?
Two other subquestions: is this behaviour defined somewhere in the ANSI standards? Is C different from C++ in this regard, or do they behave the same?
inline is non-binding with regards to whether or not a function will be inlined by the compiler. This was originally what it was intended to do. But since then, it's been realized that whether or not a function is worth inlining depends as much on the call site as the function itself and is best left to the compiler to decide.
From https://en.cppreference.com/w/cpp/language/inline :
Since this meaning of the keyword inline is non-binding, compilers are free to use inline substitution for any function that's not marked inline, and are free to generate function calls to any function marked inline. Those optimization choices do not change the rules regarding multiple definitions and shared statics listed above.
Edit : Since you asked for C as well, from https://en.cppreference.com/w/c/language/inline :
The intent of the inline specifier is to serve as a hint for the compiler to perform optimizations, such as function inlining, which require the definition of a function to be visible at the call site. The compilers can (and usually do) ignore presence or absence of the inline specifier for the purpose of optimization.
Regarding the relation between C and C++, the inline specifier is treated differently in each language.
In C++: inline functions (and function like entities, and variables (since C++17) ) that have not been previously declared with internal linkage will have external linkage and be visible from other compilation units. Since inline functions (usually) reside in header files, this means that the same function will have repeated definitions across different compilation units (this is would be a violation of the One definition rule but the inline makes it legal). At the end of the build process (when linking an executable or a shared lib), inline definitions of the same entity are merged together. Informally, C++ inline means: "there may be multiple identical definitions of some function across multiple source files, but I want them to end up as a unique definition".
In C: If extern is not explicitly specified, then an inline function definition is not visible from other translation units, different translation units may have different definitions with inline specifier for the same function name. Also, there may exist (at most) one definition for a function name that is both inline and extern and this qualifies that function as the one that is externally visible (ie gets selected when one applies the address of & operator to the function name). The One definition rule from C and its relation with extern and inline is somehow different from C++.
can a compiler automatically inline a very short function that wasn't defined as inline if the compiler believes doing so will lead to a performance gain?
Limitation:
When code uses a pointer to the function, then the function needs to exist non-inlined.
Limitation:
When the function is visible outside the local .c file (not static), this prevents simplistic inlined code.
Not a limitation:
The length of the function is not an absolute limitation, albeit a practical one.
I've worked with embedded processor that commonly inline static functions. (Given code does not use a pointer to them.)
The usefulness of the inline keyword does not affect the ability for a compiler to inline function.
When it comes to the standard, the keyword inline has nothing to do with inlining.
The rules (in c++) are basically:
A function which is not declared inline can by only defined in one translation union. It still needs to be delared in each translation unit where it is used.
A function which is declared inline has to be defined in each translation unit where it is odr-used (ord-use means to call the function or to take the pointer,...).
So, in a standard project setting it is almost always correct to follow the following two rules. Functions that are defined in a header file, are always to be declared inline. Functions defined in a *.cpp-file are never declared inline.
This said, I think the compiler cannot really draw any conclusions about the programmer wanted inlining from using or not using keyword inline. The name of the keyword is an unfortunate legacy from a bad naming.
!! Specific on frequently used methods like getter & setter. !!
I have no idea when the keyword inline should be used. Ofc I know what it does, but I still have no idea.
According to an interview with Bjarne Stroustrup he said:
My own rule of thumb is to use inlining (explicitly or implicitly) only for simple one- or two-line functions that I know to be frequently used and unlikely to change much over the years. Things like the size() function for a vector. The best uses of inlining is for function where the body is less code than the function call and return mechanism, so that the inlined function is not only faster than a non-inlined version, but also more compact in the object core: smaller and faster.
But I often read that the compiler automatically inline short functions like getter, setter methods (in this case getting the size() of a vector).
Can anyone help?
Edit:
Coming back to this after years and more experience the high performance C+++ programming, inline can indeed help. Working in the games industry even forceinline sometimes makes a difference, since not all compilers work the same. Some might inline automatically some don't.
My advice is if you work on frameworks, libraries or any heavily used code consider the use of inline, but this is just general advice anyway since you want such code to be fully optimized for any compiler. Always using inline might not be the best, because you'll also need the class definition for this part of the code. Sometimes this can increase compilation times if you can't use forward declarations anymore.
another hint: you can use C++14 auto return type deduction even with seperating the function definition:
MyClass.h
class MyClass
{
int myint;
public:
auto GetInt() const;
}
inline auto MyClass::GetInt() const { return myint; }
all in one .h file.
Actually, inline keyword is not for the compiler anymore, but for the linker.
That is, while inline in function declaration still serves for most compilers as a hint, on high optimization setting they will inline things without inline and won't inline things with inline, if they deem it better for the resulting code.
Where it is still necessary is to mark function symbols as weak and thus circumvent One Definition Rule, which says that in given set of object files you want to make into a binary, each symbol (such as function) shall be present only once.
Bjarne's quote is old. Modern compilers are pretty smart at it.
That said, if you don't use Link Time Code Generation, the compiler must see the code to inline it. For functions used in multiple .cpp files, that means you need to define them in a header. And to circumvent the One Definition Rule in that case, you must define those functions as inline.
Class members defined inside the class are inline by default, though.
The below speaks specifically to C++:
The inline keyword has nothing to do with inlining.
The inline keyword allows the same function to be defined multiple times in the same program:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
§3.2 [basic.def.odr]
Attaching meaning beyond this to the inline keyword is erroneous. The compiler is free to inline (or not) anything according to the "as-if rule":
A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input.
§1.9 [intro.execution]
Considering what compiler optimizations can do, the only use of inline I have today is for non-template function whose body is defined inside headers files outside class bodies.
Everything is defined (note: defined != declared) inside class bodies is inline by default, just as templates are.
The meaning of inline in fact is: "Defined in header, potentially imported in multiple sources, just keep just one copy of it" told to the linker.
May be in c++35 someone will finally decide to replace that keyword with another one more meaningful.
C++ standard Section 7.1.2 Point 2:
(...) 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 (...)
In other words instead of havin a single code for your function, that is called several times, the compiler may just duplicate your code in the various places the function is called. This avoids the little overhead related to the function call, at the cost of bigger executables.
Be aware that inline keyword may be used also with namespaces, but with a very different meaning. Members of an inline namespace can be used in most respects as though they were members of the enclosing namespace. (see Standard, section 7.3.1 point 8).
Edit:
The google style guide recommends to inline only when a function is ten lines or less.
I'm answering the question my self!: Solution: After a few performance tests, the rule of thumb from Stroustrup is right! inlining Short functions like the .size() from vector can improve the performance (.size() calls are used frequently). But the impact is only noticeable for FREQUENTLY used functions. If a getter/setter method is used a lot, inlining it might increase the performance.
Stroustrup:
Don’t make statements about “efficiency” of code without first doing
time measurements. Guesses about performance are most unreliable.
Edit: I've restored the original title but really what I should have asked was this: 'How do C++ linkers handle class methods which have been defined in multiple object files'
Say I have a C++ class defined in a header along these lines:
class Klass
{
int Obnoxiously_Large_Method()
{
//many thousands of lines of code here
}
}
If I compile some C++ code which uses 'Obnoxiously_Large_Method' in several locations, will the resulting object file always inline the code for 'Obnoxiously_Large_Method' or will it optimise for size (for example, when using g++ -Os) and create a single instance of 'Obnoxiously_Large_Method' and use it like a normal function?, if so, how do linkers resolve the collisions between other object files which have instantiated the same function?. Is there some arcane C++ namespace Juju which keeps the separate object instances of method from colliding with each other?
7.1.2 Function specifiers
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.
So, the compiler is not required to actually 'inline' any function.
However, the standard also says,
An inline function with external linkage shall have the same address in all translation units.
Member functions normally have external linkage (one exception is when the member function belongs to a 'local' class), so inline functions must have a unique address for cases where the address of the function is taken. In this case, the compiler will arrange for the linker to throw away all but one instance of a non-inlined copy of the function and fix-up all address references to the function to be to the one that's kept.
Section [9.3], Member functions, of the C++98 Standard states:
A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2).
Thus, it has always been the case that marking member functions defined in the class definition explicitly inline is unnecessary.
On the inline function specifier, the Standard states:
A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline specifier indicates to the [C++ compiler] that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. [However, a C++ compiler] is not required to perform this inline substitution at the point of call;
So, it is up to the compiler whether it will actually inline the definition of the function rather than call it via the usual function call mechanism.
Nothing is always inlined (unless your compiler has an attribute or private keyword to force it to do so...at which point you're writing $(COMPILER)-flavored C++ rather than standard C++). Very long functions, recursive functions, and a few other things generally aren't inlined.
The compiler can choose not to inline stuff if it determines that doing so will degrade performance, unreasonably increase the object file's size, or make things work incorrectly. Or if it's optimizing for size instead of speed. Or if you ask it not to. Or if it doesn't like your shirt. Or if it's feeling lazy today, cause it compiled too much last night. Or for any other reason. Or for no reason at all.
There is no - single answer to this question. Compilers are smart beasts. You can specifically use the inline words if you want, but this doesn't mean that the compiler will actually inline the function.
Inline is there to help the developer with optmization. It hints at the compiler that something should be inlined, but these hints are generally ignored nowadays, since compilers can do better at register assignment and deciding when to inline functions (in fact, a compiler can either inline or not inline a function at different times). Code generation on modern processors is far more complicated than on the more deterministic ones common when Ritchie was inventing C.
What the word means now, in C++, is that it can have multiple identical definitions, and needs to be defined in every translation unit that uses it. (In other words, you need to make sure it can be inlined.) You can have an inline function in a header with no problems, and member functions defined in a class definition are automatically effectively inline.
That said, I used to work with a greenhills compiler, and it actually obeyed my will more than it disobeyed it :).. It's up to the compiler, really.
The inline keyword deals with c++ definition of a function. The compiler may inline object code where ever it wants.
Functions defined inline (eg they use the inline keyword), create object code for the function in every compilation unit. Those functions are marked as special so the linker knows to only use one.
See this answer for more specifics.
It doesn't have to be inlined, no; it's just like if you specified inline explicitly.
When you write inline, you promise that this method won't be called from translation units where it isn't defined, and therefore, that it can have internal linkage (so the linker won't connect one object-file's reference to it to another object-file's definition of it). [This paragraph was wrong. I'm leaving it intact, just struck-out, so that the below comments will still make sense.]
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.
In C++, do methods only get inlined if they are explicitly declared inline (or defined in a header file), or are compilers allowed to inline methods as they see fit?
The inline keyword really just tells the linker (or tells the compiler to tell the linker) that multiple identical definitions of the same function are not an error. You'll need it if you want to define a function in a header, or you will get "multiple definition" errors from the linker, if the header is included in more than one compilation unit.
The rationale for choosing inline as the keyword seems to be that the only reason why one would want to define a (non-template) function in a header is so it could be inlined by the compiler. The compiler cannot inline a function call, unless it has the full definition. If the function is not defined in the header, the compiler only has the declaration and cannot inline the function even if it wanted to.
Nowadays, I've heard, it's not only the compiler that optimizes the code, but the linker can do that as well. A linker could (if they don't do it already) inline function calls even if the function wasn't defined in the same compilation unit.
And it's probably not a good idea to define functions larger than perhaps a single line in the header if at all (bad for compile time, and should the large function be inlined, it might lead to bloat and worse performance).
Yes, the compiler can inline code even if it's not explicitly declared as inline.
Basically, as long as the semantics are not changed, the compiler can virtually do anything it wants to the generated code. The standard does not force anything special on the generated code.
Compilers might inline any function or might not inline it. They are allowed to use the inline decoration as a hint for this decision, but they're also allowed to ignore it.
Also note that class member functions have an implicit inline decoration if they are defined right in the class definition.
Compilers may ignore your inline declaration. It is basically used by the compiler as a hint in order decide whether or not to do so. Compilers are not obligated to inline something that is marked inline, or to not inline something that isn't. Basically you're at the mercy of your compiler and the optimization level you choose.
If I'm not mistaken, when optimizations are turned on, the compiler will inline any suitable routine or method.
Text from IBM information Center,
Using the inline specifier is only a
suggestion to the compiler that an
inline expansion can be performed; the
compiler is free to ignore the
suggestion.
C Language Any function, with the exception of main, can be declared or
defined as inline with the inline
function specifier. Static local
variables are not allowed to be
defined within the body of an inline
function.
C++ functions implemented inside of a class declaration are
automatically defined inline. Regular
C++ functions and member functions
declared outside of a class
declaration, with the exception of
main, can be declared or defined as
inline with the inline function
specifier. Static locals and string
literals defined within the body of an
inline function are treated as the
same object across translation units;
Your compiler's documentation should tell you since it is implementation dependent. For example, GCC according to its manual never inlines any code unless optimisation is applied.
If the compiler does not inline the code, the inline keyword will have the same effect as static, and each compilation unit that calls the code will have its own copy. A smart linker may reduce these to a single copy.
The compiler can inline whatever it wants in case inlining doesn't violate the code semantics and it can reach the function code. It can also inline selectively - do inline when it feels it's a good idea and not inline when it doesn't feel it's a good idea or when it would violate the code semantics.
Some compilers can do inlining even if the function is in another translation unit - that's called link-time code generation.
Typical cases of when inlining would violate code semantics are virtual calls and passing a function address into another function or storing it.
Compiler optimize as he wants unless you spec the opposite.
The inline keyword is just a request to the compiler. The compiler reserves the right to make or not make a function inline. One of the major factor that drives the compiler's decision is the simplicity of code(not many loops)
Member functions are declared inline by default.(The compiler decides here also)
These are not hard and fast rules. It varies according to the compiler implementations.
If anybody knows other factors involved, please post.
Some of the situations where inline expansion may NOT work are:
For functions returning values, if a loop, a switch, or a goto exists
For function not returning values, if a return statement exits;
If functions contain static variables
If inline functions are recursive.
Inline expansion makes a program run faster because the overhead of a function call and return statement is eliminated. However, it makes the program to take up more memory because the statements that define the inline functions are reproduced at each point where the function is called. So, a trade-off becomes necessary.
(As given in one of my OOP books)