Inline declaration missing in header: Linker or Compiler Error? - c++

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)

Related

Could a very long Class function member defined in header file?

I defined a class in header file and implemented its function in same header file. I didn't put inline keyword with function definition because I think compiler will regard it as a inline function by default -- but inline is only a hint to compiler, right? What if compiler doesn't regard it as inline function because of its length? I never get error message 'multiple definitions' in reality.
struct tmp {
void print() {
...(very long)
}
};
I didn't put inline keyword with function definition because I think compiler will regard it as a inline function by default
Yes, member functions defined in the body of a class are implicitly inline. The keyword is not necessary.
inline is only a hint to compiler, right? What if compiler doesn't regard it as inline function because of its length?
Yes, sort of. Actually, the inline keyword has two meanings.
The first one is the one you are thinking of, the one that hints to the optimizer to inline the code in the function body at the call site. As you said, this is just a hint—the optimizer is free to ignore this request if it determines that it would be a performance pessimization to do so (or if it is unable to inline for some other technical reason). This meaning of the inline keyword is arguably obsolete. All optimizing compilers nowadays ignore the inline keyword because their authors consider their heuristics to be smarter than the programmer. This is almost always the case, making it rather pointless to try and second-guess the optimizer by marking your functions inline.
The second meaning of the inline keyword is to relax the one-definition rule (ODR), making it legal for there to be multiple definitions of the same function visible to the linker. (Although the behavior of the linker under such circumstances is an implementation detail, most of them will just arbitrarily pick one of the definitions. Which of course only works out well if they are all the same.) This meaning of the inline keyword is still very important, and explains why it is still used today in code.
This is the meaning that your code is benefitting from. Since member functions defined in the body of a class are implicitly marked inline, you do not get multiply-defined symbol errors from the linker.
If you had defined the function in the header file but not within the class definition—in other words, if you had done this:
struct tmp {
void print();
};
void tmp::print()
{ ... }
then you would start getting the multiply-defined symbol errors as soon as that header file was included in two or more compilands (i.e., translation units). This is where you would need to add the inline keyword on the function's definition, not because you want the compiler to "inline" it, but because you want to exempt yourself from the ODR.
EDIT #Leon (below) stated that my answer (reproduced below) was INCORRECT. The correct answer is described here - in short, if the compiler decides to not make a function inline, it still puts it in the object module. But the linker will then pick one of the (potentially many) copies in the different modules and discard all the others.
You are right: you won't get the "multiple definition" error because every time the compiler decides to not put a function inline, it makes the function static within the current module. That means that you could have a large number of copies of your large function littered through your code.

how the compiler processes inline functions defined in cpp file

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.

Does defining a function inside a header always make the compiler treat it as inline?

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.

When do compilers inline C++ code?

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)

Are free functions implicitly inlined if defined without a previous declaration in C++?

Is the following free function implicitly inlined in C++, similar to how member functions are implicitly inlined if defined in the class definition?
void func() { ... }
Do template functions behave the same way?
It depends what you mean by inlined. A compiler can optimise any function by placing its emitted code inline at the call site. However, if you mean does the code you ask about behave as if it was declared:
inline void func() { ... }
then the answer is no. If you place your code in two different compilation units and build the executable, you will get multiple definition errors. If you explicitly mark the function as "inline", you will not.
Regarding template functions, then some part of the compilation system will see to it that multiple instantiations of the same template do not cause multiple definition errors.
No, it's not implicitly inlined. The compiler has no way of knowing if another module will use this function, so it has to generate code for it.
This means, for instance, that if you define the function like that in a header and include the header twice, you will get linker errors about multiple definitions. Explicit inline fixes that.
Of course, the compiler may still inline the function if it thinks that will be efficient, but it's not the same as an explicit inlining.
Template functions are implicitly inlined in the sense that they don't require an inline to prevent multiple definition errors. I don't think the compiler is forced to inline those either, but I'm not sure.
It might be inlined, depending on if the compiler decides to make it inline or not.