We know that calling inline function is replaced by its function body in the preprocess procedure before compiling. However, if the inline function is just declared in head file while defined in a cpp file, does the compiler know how to replace? Does the cimpiler only know the inline function's declaration but not know the definition right now?
Thanks.
Inline functions are handled entirely by the compiler, not the preprocessor.
An inline function must be defined in every translation unit where it is odr-used (§3.2/3).
In other words, if there's a call to an inline function in a file, then the definition (not just a declaration) of that inline function must appear in the pre-processed version of that file.
No diagnostic is (currently) required for breaking this rule. The compiler could reject the code outright, or it could (for example) continue to compile and treat that function as a normal (not inline) function. You're pretty much at the mercy of the compiler though--you're clearly breaking the rules of the language, so the only real question is whether the compiler will really enforce the rules, or possibly let you get away with breaking them in this particular case.
However, if the inline function is just declared in head file while
defined in a cpp file, does the compiler know how to replace?
No, it doesn't. You need to include the inline function definition in the header file; if you do not, then you will get linker errors when you compile files other than the one that defines the function (but which include the header and try to call the function).
Also, note that inlining is done by the compiler and not the preprocessor.
Related
After searching for an answer for a while, I am now even more confused than before...
I am wondering if I declare in the header file an inline function that is not implemented, but called in the main function, will this result in an linker or compiler error?
When I look at the error I get undefined reference to 'A::a()' it seems like a linker error.
However, in some discussions it says that the Compiler MUST see the function delcaration, therefore it would be an Compiler Error.
I hope you can tell me what I am getting wrong here :)
Header:
Main function:
It is a linker error in most compilers when you have a functon declaration, but the implementation (definition) of the function is not present.
Technically, the compiler MAY report that an inline function is not present in the source, but the compiler is not obliged to do so, and code exists that do not always define the function that is declared as inline. It is not, in most compilers, an error to declare a function inline, and define it in a separate compilation unit (different source file), so compilers do not give an error by default.
If the compiler doesn't find the definition for an inline function, the compiler will assume that it's an external function, and the linker is the only place were all of the code comes together, and thus "it's not there" is issued by the linker.
To clarify:
You may well have a situation where you want to declare as inline a function but put the implementation of a function in a source-file (perhaps because it's never called anywhere else, there is a single factory function to instantiate all instances of that class). Then it is perfectly legal to declare the function [such as a constructor] as inline in the header-file, and the place the implementation of the function in a source file, using the object in various other files without an implementation present.
In practice, compilers also allow the calling of inline functions, even when they are only declared in a source file, not the header. The compiler will not always inline those functions [in practice, only "link time optimization" or "whole program optimization" are likely to do that].
It depends on the compiler you are using but as far as I remember an inline declaration is by default a recommendation to the compiler. In your case, since the compiler didn't find the implementation of the function it will not implement it inline and will leave it to the linker to link.
If you are using GCC you can force the compiler to do inline, see more details in this blog:
Force inline functions in C++(GCC)
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.
This question arose while I was implementing my static library.
I want to check my guess and gain information on using inline functions in static libs.
My guess is that an iplementator of a static lib can not export an inline function in his library
Due to the inline statement is
implemented by a compiler(it is up to the compiler whether to make
the function inline) by placing low level commands representing
operations in the function body to the code segment so that
operations won't be placed in the tables of export/import and
therefore can't be processed by linker and therefore can't be
included by librarian to the code of application to which static lib
is attached. Is my logic right?
I guess that importing function as inline is allowed but I wonder how it is implemented, because it is compiler`s
responsibility but on the linkage state there is only librarian, so
that means that it must undertake some actions in order to make
function inline.
Yes, inline functions are typically placed in a header, so the function body is directly visible to the compiler everywhere the function is used. This lets the compiler evaluate whether to generate inline code for the function in any particular instance.
This basically doesn't arise -- "An inline function shall be defined in every translation unit in which it is odr-used." (§3.2/3). That means if the compiler is going to generate the function inline, what goes into the library is object code that includes inline expansion of the code for that function. Since it's possible that function may not be expanded inline at every use, there will also typically be a definition of the function in the library, but that definition will be used (at least primarily) like a normal function, not expanded inline.
Linkers can also generate code though. Regardless of whether a function is or isn't an inline function by the language standard, and is defined in the same or a different translation unit from the one where it's used, the linker may be able to generate inline code for it anyway.
To make a long story short, the inline keyword has little or no effect on a typical compiler as far as whether a function's code will be generated inline or not. The main (if not sole) effect is that it changes the one-definition rule -- being inline means that multiple (identical) definitions of the same function can exist without causing a problem.
Do you understand the keyword inline - you could equally use replace.
An inline function enables the compile if so choosing to replace the function call with the actual code - nothing to export/import. It is defined in the header file. Anything that uses the object code will require that header code and thus the compiler will replace the function call with the actual code.
On Visual C++ you can use Microsoft specific behavior, and export/import inline functions with __declspec(dllexport) inline or extern inline. Note that this is Microsoft specific behavior, if you target anything but Windows and are not concerned at all with portability, you could consider it.
I defined a function show() as inlined in a header file called ex.h and the definition of the function inside ex.cpp. I expected that this will give me an error since the compiler will not know what to replace where the show() function is called. But because I'm using an IDE, it worked fine. How could this happen?
And BTW when I tried to compile it manually it gave me an error that the show() is used but not defined.
It's imperative that the function's definition (the part between the {...}) be placed in a header file, unless the function is used only in a single .cpp file.
In particular, if you put the inline function's definition into a .cpp file and you call it from some other .cpp file, you'll get an "unresolved external" error from the linker.
[read more]
We usually put the inline function in the header file, so the compiler can see the definition while compiling the code that uses the function. That way it works with all compilers.
Some compilers have features for optimizing the whole program at once (Whole program optimization or Link time optimization). These compilers can inline a function even if it is defined in a different .cpp file.
Normally the entire inline functions lives in the .h
The reason is the compiler has to see the entire inline definition up front. Inline functions are compiled by directly 'pasting' the emitted machine language.
I just learned that defining a c++ function inside a class's header file make the function inline. But I know that putting the inline keyword next to a function is only a suggestion and the compiler wont necessarily follow it. Is this the same for header defined c++ functions and is there a difference in behavior between a standalone c++ function and a c++ function that is part of a class?
"defining a c++ function inside a class's header file make the function inline"
That's not true. Defining a function (that is to say, providing the body of the function instead of just a declaration) inside a class definition makes it inline. By "makes it inline", I mean it's the same as giving it the inline keyword. But class definitions don't have to be in headers, and headers can contain other things than class definitions.
So in this example, the function foo is implicitly inline. The function bar is not implicitly inline:
struct Foo {
void foo() {}
void bar();
};
void Foo::bar() {}
"putting the inline keyword next to a function is only a suggestion and the compiler wont necessarily follow it"
inline has two effects. One of them is a hint to the compiler which it can ignore. The other is not optional, and always has its effect. The "hint" is that the compiler is advised to replace calls to that function with a copy of the code for the function itself.
The guaranteed effect is that an inline function can be defined in multiple translation units, and those be linked together, without a multiple definition error, and all but one of the copies is removed by the linker. So, if the example above appears in a header file which is shared between multiple translation units, bar needs to be explicitly marked inline. Otherwise, the linker will discover multiple definitions of bar, which is not allowed.
Despite the name, inline in C++ is mostly about the second, compulsory effect, not the first, optional one. Modern optimising compilers have their own ideas about which calls should be inlined, and don't pay a whole lot of attention to inline when making that decision. For instance I've seen it have an effect in gcc at moderate optimisation levels, but at low levels approximately nothing is inlined, and at high levels approximately everything is (if the definition is available when the call is compiled) unless it makes the function too big.
Whether a function is defined in a header or in a cpp file has absolutely no effect on anything by itself. You can safely imagine that what #include does is copy and paste the header file into the cpp file in the preprocessor, before the compiler ever sees it. If a function is defined in the same translation unit as a call to it, then the function code is available to be inlined by the compiler. If they're in different translation units, then the code is not available and the call can only be inlined by the linker, with whole-program optimisation or similar. A "translation unit" more or less means, "a cpp file, after all the headers have been copy and pasted into it".
C++ compilers are free to choose what will be inline and what won't, no matter what hints you give them. It shouldn't matter if the function is part of a class or not, or whether it is in a header file or source file; the compiler doesn't pay attention to those things while making its decision.
No, not always. The compiler treats it as a hint, just like the inline keyword, but it mostly decides on its own, because it knows better than you what the costs and benefits may be. Inlining the code avoids the function call overhead, but makes the code bigger, which has negative performance impacts on the instruction cache.
These performance hints from the programmer are generally more and more often ignored by the compiler. What it does not ignore (or rather, what the linker does not ignore) is that a function declared inline may appear in several compilation units, and should be treated as multiple copies of the same function without resulting in linker errors.
If you place the definition of a free non-template function in a header file, you will end up with a function definition in each .cpp file that includes the header (directly or indirectly). This can lead to problems when linking.
However, if you declare the function to be inline, the linker will make sure you only use a single definition even if it is included at multiple places.