I know that the inline keyword is only a hint for the compiler, and not forced (unless using __forceinline e.g. in MSVC).
Is it also the case when declaring the inlined function in header? In which compilation unit will the compiler put the code?
inline is not just a hint to the compiler.
An inline function may be defined in multiple translation units, and all of these definitions will have the same type, address, and definition.
If a function is defined in a header, then it must be declared inline, or it will violate the One Definition Rule when it is included in multiple translation units.
An inline function is either:
A function at global scope can be declared inline using the keyword inline.
A function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function, is always inline.
A function declared constexpr is always inline.
(source)
Is it also the case [that inline is a hint] when declaring the inlined function in header?
Yes. The inline keyword is always a hint to the compiler to perform "inlining".
However, please note that this is only a hint. The compiler is free to ignore it (and many do).
The real reason compilers are able to perform inlining on inline functions is that the whole definition is available. You will notice the same inlining with static functions and instantiated function templates.
In which compilation unit will the compiler put the code?
Before linkage, the inline function will be fully defined in any compilation unit that defines it. It will be compiled in its entirety into each object file.
During linkage, the linker will determine which definition to use, and discard all the others.
See also this question and its answers.
The code will be present in all compillation units that include this header. The main point of inline is saying to the linker that this function can be found in multiple object files and any of these copies can be chosen by linker.
Inline is not forced, ever. If you define a method inside the class definition, it is implicitly inlined. It's like defining it outside the class definition except with inline implied. This has nothing to do with what file the definition is in.
When a function you requested to inline is not actually inlined, it's up to the compiler to decide where to put it. In early days, you could get a non-exported copy in each file that header file was included in. Now, some strategy is applied like putting it in the same place as the first constructor, the first method, or where the virtual function table is. It's compiler-dependent.
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.
I need to define inline functions to improve performance of my code. At the moment declaration of functions are in .h file and definitions are in .cpp file. I added inline keyword at the front of each declaration of functions but I am getting link error. Is possible to separate declaration and definition of inline functions ?
You can separate the declaration and definition fine, but that definition must be available in every translation unit that uses the function, e.g.:
#include <iostream>
inline void foo();
int main() {
foo();
}
inline void foo() {
std::cout << "Hi\n";
}
is perfectly legal and correct.
The exact quote from n3290 § 7.1.2.4 is:
An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly
the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its
definition appears in the translation unit. —end note ]
Where § 3.2 basically says that it has to be identical everywhere, even overload resolutions etc.
Are you absolutely sure that making your functions 'inline' would improve your performance? I am pretty sure it will not.
The compiler is able to inline some function calls if and only if it can see the body of the inlined functions. So you need to include the body of the function as well, but if do it, you do not need to annotate your function with 'inline' because the compiler only needs the body of the function -- not your 'inline' keyword. Compilers nowadays are smart and know without your hints whether and when to inline functions. And inlining does not necessarily increase your program's performance, and it is likely to increase your executable's size.
See this article by Herb Sutter. He argues that keyword "inline" has no meaning in C++. But I disagree with him. Keyword "inline" makes one difference: you can specify the body of the inline function more than once in the program (provided that it is exactly the same definition each time) -- this is useful when putting function bodies in headers (if you need this for any reason).
Yes, but you have to put the implementation in the header file. That is because in order to be inlined, the definition has to be known, when including the header.
If you do so, modern compilers will automatically inline the function even without the inline keyword.
Use a separate "implementation header" that you will still include everywhere?
You are need specify only once prototype or realization. Both is eligible.
By definition, inline functions must be known at compile time.
If you want to define them in a separate .h file, you can use a
#pragma once
trick to only insert their definition once.
I have found that in some embedded toolchains, the #inline keyword is not allowed in the function declaration. You can specify it in the definition, but (as stated above) many compilers ignore the keyword anyway.
What's the difference between using the inline keyword before a function and just declaring the whole function in the header?
so...
int whatever() { return 4; }
vs
.h:
inline int whatever();
.cpp:
inline int myClass::whatever()
{
return 4;
}
for that matter, what does this do:
inline int whatever() { return 4; }
There are several facets:
Language
When a function is marked with the inline keyword, then its definition should be available in the TU or the program is ill-formed.
Any function defined right in the class definition is implicitly marked inline.
A function marked inline (implicitly or explicitly) may be defined in several TUs (respecting the ODR), whereas it is not the case for regular functions.
Template functions (not fully specialized) get the same treatment as inline ones.
Compiler behavior
A function marked inline will be emitted as a weak symbol in each object file where it is necessary, this may increase their size (look up template bloat).
Whereas the compiler actually inlines the call (ie, copy/paste the code at the point of use instead of performing a regular function call) is entirely at the compiler's discretion. The presence of the keyword may, or not, influence the decision but it is, at best, a hint.
Linker behavior
Weak symbols are merged together to have a single occurrence in the final library. A good linker could check that the multiple definitions concur but this is not required.
without inline, you will likely end up with multiple exported symbols, if the function is declared at the namespace or global scope (results in linker errors).
however, for a class (as seen in your example), most compilers implicitly declare the method as inline (-fno-default-inline will disable that default on GCC).
if you declare a function as inline, the compiler may expect to see its definition in the translation. therefore, you should reserve it for the times the definition is visible.
at a higher level: a definition in the class declaration is frequently visible to more translations. this can result in better optimization, and it can result in increased compile times.
unless hand optimization and fast compiles are both important, it's unusual to use the keyword in a class declaration these days.
The purpose of inline is to allow a function to be defined in more than one translation unit, which is necessary for some compilers to be able to inline it wherever it's used. It should be used whenever you define a function in a header file, although you can omit it when defining a template, or a function inside a class definition.
Defining it in a header without inline is a very bad idea; if you include the header from more than one translation unit, then you break the One Definition Rule; your code probably won't link, and may exhibit undefined behaviour if it does.
Declaring it in a header with inline but defining it in a source file is also a very bad idea; the definition must be available in any translation unit that uses it, but by defining it in a source file it is only available in one translation unit. If another source file includes the header and tries to call the function, then your program is invalid.
This question explains a lot about inline functions What does __inline__ mean ? (even though it was about inline keyword.)
Basically, it has nothing to do with the header. Declaring the whole function in the header just changes which source file has that the source of the function is in. Inline keyword modifies where the resulting compiled function will be put - in it's own place, so that every call will go there, or in place of every call (better for performance). However compilers sometimes choose which functions or methods to make inline for themselves, and keywords are simply suggestions for the compiler. Even functions which were not specified inline can be chosen by the compiler to become inline, if that gives better performance.
If you are linking multiple objects into an executable, there should normally only be one object that contains the definition of the function. For int whatever() { return 4; } - any translation unit that is used to produce an object will contain a definition (i.e. executable code) for the whatever function. The linker won't know which one to direct callers to. If inline is provided, then the executable code may or may not be inlined at the call sites, but if it's not the linker is allowed to assume that all the definitions are the same, and pick one arbitrarily to direct callers to. If somehow the definitions were not the same, then it's considered YOUR fault and you get undefined behaviour. To use inline, the definition must be known when compiler the call, so your idea of putting an inline declaration in a header and the inline definition in a .cpp file will only work if all the callers happen to be later in that same .cpp file - in general it's broken, and you'd expect the (nominally) inline function's definition to appear in the header that declares it (or for there to be a single definition without prior declaration).
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.]
If a header file contains a function definition it can be inlined by the compiler. If the function is exported, the function's name and implementation must also be made available to clients during linkage. How does a compiler achieve this? Does it both inline the function and provide an implementation for external callers?
Consider Foo.h:
class Foo
{
int bar() { return 1; }
};
Foo::bar may be inlined or not in library foo.so. If another piece of code includes Foo.h does it always create its own copy of Foo::bar, whether inlined or not?
Header files are just copy-pasted into the source file — that's all #include does. A function is only inline if declared using that keyword or if defined inside the class definition, and inline is only a hint; it doesn't force the compiler to produce different code or prohibit you from doing anything you could otherwise do.
You can still take the address of an inline function, or equivalently, as you mention, export it. For those uses, the compiler simply treats it as non-inline and uses a One Definition Rule (the rule which says the user can't apply two definitions to the same function, class, etc) to "ensure" the function is defined once and only one copy is exported. Normally you are only allowed to have one definition among all sources; an inline function must have one definition which is repeated exactly in each source it is used.
Here is what the standard has to say about inline extern functions (7.1.2/4):
An inline function shall be defined in
every translation unit in which it is
used and shall have exactly the same
definition in every case (3.2). [Note:
a call to the inline function may be
encountered before its defi- nition
appears in the translation unit. ] If
a function with external linkage is
declared inline in one transla- tion
unit, it shall be declared inline in
all translation units in which it
appears; no diagnostic is required. An
inline function with external linkage
shall have the same address in all
translation units. A static local
variable in an extern inline function
always refers to the same object. A
string literal in an extern inline
function is the same object in
different translation units.
It usually means that it ends up creating a separate inlined method for every obj file that uses it at link time. It can also fail or refuse to inline many things, so this can cause a problem because you can wind up with bloated objs without getting the performance benefitting of inlining. The same thing can happen with virtual method inlining so it can be worth forcing inining and setting warning for inline failure (about the only useful warning message compilers give).
By export, I'm guessing you mean something such as getting a pointer to the function and later calling the function through the pointer.
Yes, in that case, the compiler will generate a regular function so that it can be invoked from a pointer.
One way to do this is with a link-once section. The idea is that in translation unit gets the code in a special type of section that has a name based on the function name. During linking, the linker will only keep one instance of identically named link-once sections.
inlined functions do not exist in the compiled binary: that is because they are taken and placed directly at the call site (so called IN-LINE). Each usage of the inlined function results in the complete code to be pulled in at that place.
So inlined functions cannot be exported because they do not exist. But you can still use them if you have a definition in one header. And yes, you MUST provide a definition for an inlined function, otherwise you cannot use it.
If you managed to export an inlined function then it is sure that it is not inline anymore: inline is not a strict semantic element. Depending on the compiler and compiler settings, one compiler might choose to inline, another not, sometimes provide a warning, sometimes even an error (which personnally I would prefer being the default behaviour, because it shows up the places where unintended things occur)