Inline functions in C++ - c++

Hii ,
I am a novice in C++. I did read about inline functions and understood them right. But this site says that "We get an 'unresolved external' error if we write the definition of an inline function in one .cpp file and call it from another file....why is that so ... ?
This can be done for normal functions right...Please correct me if i am wrong ...
Thanks

It's a language requirement. inline means that you may have the function defined in more than one translation unit but the definitions must be identical and that you must have a definition in every translation unit that uses the function.
Those are the rules. The rules allow (but don't require) the compiler to expand the code for the inline function at each call site and omit emitting a callable function version.
This is different from non-inline functions which must only be defined once across all translation units. This is the usual "one definition rule" which applies to most entities in C++.
inline doesn't change the linkage of a function. inline functions have, by default, external linkage so if you use a static variable inside an inline function the implementation must ensure that there is only one copy of that variable in the program.

Keep in mind that the compiler operates on a file-by-file basis, i.e. it treats each .cpp file as its own discrete unit. There is no connection between each one of them (except of course references to other functions and variables that are glued together by the linker).
If you inline something, and if the compiler decides to take you by the word (remember that inline is a hint, which means the compiler can choose to ignore you), it will embed the function into the code of whichever other block is calling it, so there will be no function that the linker can point other .cpp files two.
As an example:
File a.cpp:
void func1() {
// code...
}
This will create an object file (like a.obj) which contains the code for func1 in a way that others can call it. The linker will be able to tell other .cpp files to go there.
File b.cpp:
void func2() {
func1();
}
This will create b.obj which contains func2 with a function call to func1. The code has no idea what func1 does, it just has a branch here and asks the linker to put the right address in once everything has been compiled.
This is all nice an good, but if a.cpp only had an inlined version of func1, the linker will have nothing to give func2() to.

Related

Defining a member function inside the class instead of outside in C++?

By writing the definition of a member function inside the class in the header file as follows, I was told that compiler treats this as an inline function - hence , anywhere it encounters this function being called in the program , it enters the complete body of the function every time instead of jumping to the one location where the function resides in memory. Is this true?
class myClass
{
public:
void Fun1()
{
//implemented here
}
}
I was told that compiler treats this as an inline function
Correct. That means that it's allowed to be defined in more than one translation unit, which is necessary if you want to define it in a header and include that header more than once in your program.
Hence , anywhere it encounters this function being called in the program , it enters the complete body of the function every time instead of jumping to the one location where the function resides in memory
No, that's not what inline means in the context of a function definition. That's the optimisation of function call inlining, which the compiler can apply to any call if it thinks it will improve the code.
The two concepts are loosely related: compilers which process a single translation unit at a time will only be able to apply the optimisation to functions defined in the current unit, so they'll need to have multiple definitions to be able to optimise them in more than one unit.
If your question is whether this is equivalent to:
class myClass
{
public:
void Fun1();
};
inline void myClass::Fun1()
{
//implemented here
}
the answer is: YES.
If your question is whether the function will be physically expanded inline, the answer is: UNDEFINED. Depends on compiler's optimization flags and rules how it works.
The meaning of "inlining" in C++ is: if the compiler emits this function as out-of-line (either by not expanding at all or as alternative), it undergoes weak (vague) linkage (two such functions in two different object files linked together results in taking the first one as a good deal).
That's in contrast to normal external function, which undergo strong linkage (two such functions in two different object files linked together results in linker error).
If you define a function within a class definition, it is by default inline ( without needing to specify 'inline')
The compiler replaces all instances of an inline function call with the actual code.
Note: the compiler may ignore the 'inline' qualifier of a function if it is more than one line. You will also need to recompile all componnents (the ones which utilize that function) so that compiler can replace the code block with the new code.
You are right that the function with definition in the header file is implicitly "inline". But the inline keyword is just a hint to the compiler. Depending on its implementation, on the function contents and on the optimization flags, the compiler may decide to inline a function or not.

Inline keyword vs header definition

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).

What's the difference between inline member function and normal member function?

Is there any difference between inline member function (function body inline) and other normal member function (function body in a separate .cpp file)?
for example,
class A
{
void member(){}
};
and
// Header file (.hpp)
class B
{
void member();
};
// Implementation file (.cpp)
void B::member(){}
There is absolutely no difference.
The only difference between the two is that the member inside the class is implicitly tagged as inline. But this has no real meaning.
See: inline and good practices
The documentation says that the inline tag is a hint to the compiler (by the developer) that a method should be inlined. All modern compilers ignore this hint and use there own internal heuristic to determine when a method should be inlined (As humans are notoriously bad and making this decision).
The other use of inline is that it tells the linker that it may expect to see multiple definitions of a method. When the function definition is in the header file each compilation unit that gets the header file will have a definition of the function (assuming it is not inlined). Normally this would cause the linker to generate errors. With the inline tag the compiler understands why there are multiple definitions and will remove all but one from the application.
Note on inlining the processes: A method does not need to be in the header file to inlined. Modern compilers have a processes a full application optimization where all functions can be considered for inlining even if they have been compiled in different compilation units. Since the inline flag is generally ignored it make no difference if you put the method in the header or the source file.
Ignore the word inline here and compiler hints because it is not relevant.
The big practical difference in A and B is when they are used in different libraries.
With the case of A you can #include the header and are not required to link against anything. So you can use this class from different applications / libraries without any special linkage.
With the case of B, you need B.cpp and this should be compiled only into one library / application. Any other library or application that needs to use this class will need to link against the one that contains the actual body of the code.
With some setups / implementations you will need to specifically mark the class as "exported" or "imported" between libraries (for example with Windows you can use dllimport / dllexport and with GNU you can use attribute(visibility="default") )
The first one is implicitly inline, i.e. suggesting the compiler to expand it at the call site.
Other than the inline thing, there's a difference in that you could put more definitions in between the definition of class B, and the definition of the function.
For example, B.cpp might include header files that B.hpp doesn't, which can make a significant difference to the build process for large projects.
But even without a separate translation unit, you can occasionally have a circular dependency that's resolved by separating the definitions. For example the function might take a parameter of a type that's forward-declared before B is defined, then defined by the time the function is defined. If that type uses the definition of B in its own definition, it can't just be be defined before B.

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.

How does a compiler deal with inlined exported functions?

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)