Defining a member function inside the class instead of outside in C++? - 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.

Related

Declare member function inline without inlining it [duplicate]

See title: what does it mean for a C++ function to be inline?
It means one thing and one thing only: that the compiler will elide multiple definitions of the function.
A function normally cannot be defined multiple times (i.e. if you place a non-inline function definition into a header and then #include it into multiple compilation units you will receive a linker error). Marking the function definition as "inline" suppresses this error (the linker ensures that the Right Thing happens).
IT DOES NOT MEAN ANYTHING MORE!
Most significantly, it does NOT mean that the compiler will embed the compiled function into each call site. Whether that occurs is entirely up to the whims of the compiler, and typically the inline modifier does little or nothing to change the compiler's mind. The compiler can--and does--inline functions that aren't marked inline, and it can make function calls to functions that are marked inline.
Eliding multiple definitions is the thing to remember.
The function is placed in the code, rather than being called, similar to using macros (conceptually).
This can improve speed (no function call), but causes code bloat (if the function is used 100 times, you now have 100 copies).
You should note this does not force the compiler to make the function inline, and it will ignore you if it thinks its a bad idea. Similarly the compiler may decide to make normal functions inline for you.
This also allows you to place the entire function in a header file, rather than implementing it in a cpp file (which you can't anyways, since then you get an unresolved external if it was declared inline, unless of course only that cpp file used it).
As well as the other (perfectly correct) answers about the performance implications of inline, in C++ you should also note this allows you to safely put a function in a header:
// my_thing.h
inline int do_my_thing(int a, int b) { return a + b; }
// use_my_thing.cpp
#include "my_thing.h"
...
set_do_thing(&do_my_thing);
// use_my_thing_again.cpp
...
set_other_do_thing(&do_my_thing);
This is because the compiler only includes the actual body of the function in the first object file that needs a regular callable function to be compiled (normally because it's address was taken, as I showed above).
Without the inline keyword, most compilers would give an error about multiple definition, eg for MSVC:
use_my_thing_again.obj : error LNK2005: "int __cdecl do_my_thing(int,int)" (?do_my_thing##YAHHH#Z) already defined in use_my_thing.obj
<...>\Scratch.exe : fatal error LNK1169: one or more multiply defined symbols found
#OldMan
The compilers only inline non marked as inline functions ONLY if you request it to do so.
Only if by "request" you mean "turn on optimizations".
Its correct only on the effcts nto the casuse.
It's correct in both.
Inline do not generate any extra info that the linker may use. Compiel 2 object files and check. It allow multiple definitions exaclty because the symbols are not exported! Not because that is its goal!
What do you mean, "the symbols are not exported"? inline functions are not static. Their names are visible; they have external linkage. To quote from the C++ Standard:
void h();
inline void h(); // external linkage
inline void l();
void l(); // external linkage
The multiple definitions thing is very much the goal. It's mandatory:
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 definition
appears in the translation unit. ] If a function with external linkage is declared inline in one translation
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.
The function body is literally inserted inside the caller function. Thus, if you have multiple calls to this function, you get multiple copies of the code. The benefit is you get faster execution.
Usually very short function are inlined, when the copy of the function body would be not much bigger than the usual prologue/epilogue code generated for the normal function call.
You can read more at MSDN article about inline - http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
Inline functions alter the performance profile of your application by possibly generating instructions that are placed in the code segment of your application. Whether a function is inlined is at the discretion of your compiler. In my experience, most modern compilers are good at determining when to comply with a user's request to inline.
In many cases, inlining a function will improve its performance. There is an inherent overhead to function calls. There are reasons, however, why inlining a function could be negative:
Increasing the size of the binary executable by duplicating code could lead to disk thrashing, slowing your application down.
Inlining code could contribute to cache misses, or possibly contribute to cache hits depending on your architecture.
The C++ FAQ does a good job of explaining the intricacies of the keyword:
http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.3
Informally, it means that compilers are allowed to graft the contents of the function onto the call site, so that there is no function call. If your function has big control statements (e.g., if, switch, etc.), and the conditions can be evaluated at compile time at the call site (e.g., constant values used at call site), then your code ends up much smaller (the unused branches are dropped off).
More formally, inline functions have different linkage too. I'll let C++ experts talk about that aspect.
Calling a function imposes a certain performance penalty for the CPU over just having a linear stream of instructions. The CPU's registers have to be written to another location, etc. Obviously the benefits of having functions usually outweigh the performance penalty. But, where performance will be an issue, for example the fabled 'inner loop' function or some other bottleneck, the compiler can insert the machine code for the function into the main stream of execution instead of going through the CPU's tax for calling a function.
A function that you flag as inline is allowed to be inlined by the compiler. There is no guarantee that compielr will do it. The compiler itself uses complex semantics to device when to do it or not.
When the compiler decides that a function should be inlined, the call to the function, in the caller code is replaced by the code of the calee. This means you save up stack operations, the call itself and improve locality of code cache. Sometimes that may lead to huge performance gains. Specially in 1 line data access functions, like the accessors used in Object Oriented code.
The cost is that usually that will result in larger code, what might hurt performance. This is why setting a function to inline is only a "green flag" to the compiler, that it does not need to follow. The compiler will try to do what is best.
As a rule of thumb for beginners that don't want to deal with linkage peculiarities. inline function are to be called by other function in same compilation units. If you want to implement an inline function that can be used on multiple compilation units, make it an header file declared and implemented inline function.
Why?
Example: at header file inlinetest.h
int foo();
inline int bar();
At the compilation unit inlinetest.cpp
int foo(){ int r = bar(); return r; }
inline int bar(){ return 5;};
Then at the main.cpp
#include "inlinetest.h"
int main()
{
foo();
//bar();
}
Compile one object file at a time. If you uncomment that "bar" call you will have an error. Because the inline function is only implemented on the inlinetest.o object file and is not exported. At same time the foo function, very likely has embedded on it the code of the bar function (since bar is single line no I/O operation then its very likely to be inlined)
But if at the header file you had declared the inline function and implemented it inline then you would be able to use it at any compilation unit that includes that header.
("code sample");
Remove the inline keyword and compiler will NOT cause the error even with bar call at main And no inline will happen unless you ask the compiler to inline all functions. That is not standard behavior on most compilers.

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

Are C++ class methods defined in the header always inlined?

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

Inline functions in C++

If we define a member function inside the class definition itself, is it necessarily treated inline or is it just a request to the compiler which it can ignore.
Yes, functions that are defined inside a class body are implicitly inline.
(As with other functions declared inline it doesn't mean that the complier has to perform inline expansion in places where the function is called, it just enables the permitted relaxations of the "one definition rule", combined with the requirement that a definition must be included in all translation units where the function is used.)
As stated by others, a method defined within a class is automatically requested inline.
It's useful to understand why.
Suppose it weren't. You'd have to generate code for such a function, and everywhere it is called, a jump to subroutine instruction would have to reference the location, via the linker.
class A {
public:
void f() { ... your code ... }
};
Every time this code is seen, if it's not inline, the compiler can only assume it must be generated, so it would generate a symbol. Suppose it was like this:
A__f_v:
If that symbol were global, then if you happened to include this class code multiple times in different modules, you would have a multiply defined symbol error at link time. So it can't be global. Instead, it's file local.
Imagine you include the above header file in a number of modules. In each one, it's going to generate a local copy of that code. Which is better than not compiling at all, but you're getting multiple copies of the code when you really need only one.
This leads the the following conclusion: if your compiler is not going to inline a function, you are significantly better off declaring it somewhere once, and not requesting it to be inlined.
Unfortunately, what is and is not inline is not portable. It's defined by the compiler writer. A good rule of thumb is to always make every one liner, particularly all functions which themselves just call a function, inline, as you remove overhead. Anything below three lines of linear code is almost certainly ok. But if you have a loop in the code, the question is whether the compiler will allow it inline, and more to the point, how much benefit you would see even if it did what you want.
consider this inline code:
inline int add(int a, int b) { return a + b; }
It's not only almost as small as the prototype would be in source code, but the assembly language generated by the inline code is smaller than the call to a routine would be. So this code is smaller, and faster.
And, if you happen to be passing in constants:
int c= add(5,4);
It's resolved at compile time and there is no code.
In gcc, I recently noticed that even if I don't inline code, if it's local to a file, they will sneakily inline it anyway. It's only if I declare the function in a separate source module that they do not optimize away the call.
On the other end of the spectrum, suppose you request inline on a 1000 line piece of code. Even if your compiler is silly enough to go along with it, the only thing you save is the call itself, and the cost is that every time you call it, the compiler must paste all that code in. If you call that code n times, your code grows by the size of the routine * n. So anything bigger than 10 lines is pretty much not worth inlining, except for the special case where it is only called a very small number of times. An example of that might be in a private method called by only 2 others.
If you request to inline a method containing a loop, it only makes sense if it often executes a small number of times. But consider a loop which iterates one million times. Even if the code is inlined, the percentage of time spent in the call is tiny. So if you have methods with loops in it, which tend to be bigger anyway, those are worth removing from the header file because they a) will tend to be rejected as inline by the compiler and b) even if they were inlined, are generally not going to provide any benefit
It is necessarily treated by the compiler as a request for inline -- which it can ignore. There are some idioms for defining some functions in the header (e.g. empty virtual destructors) and some necessary header definitions (template functions), but other than that see GotW #33 for more information.
Some have noted that the compiler may even inline functions you never asked it to, but I'm not sure whether that would defeat the purpose of requesting to inline a function.
It is indeed inlined - but any inline request can be ignored by the compiler.
It is a request to the compiler that it can ignore.
The 2003 ISO C++ standard says
7.1.2/2 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.
7.1.2/3 A function defined within a class definition is an inline
function. The inline specifier shall
not appear on a block scope function
declaration.
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.
There are two things that shouldn't be lumped together:
How you mark a function as being inline: define it with inline in front of the signature or define it at declaration point;
What the compiler will treat such inline marking: regardless of how you marked the function as inline it will be treated as a request by the compiler.

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)