Writing a function in a .h file and its implementation right after (implicit inline), while using the virtual keyword:
virtual void g(){cout<<"is Inline?"};
Is the virtual functionality meaningless because the function is implemented in the .h?
Is this considered to be an inline?
Is the virtual functionality meaningless because the function is implemented in the .h?
No. virtual and inline are completely independent concepts.
virtual means that the function to call is chosen, at run-time if necessary, according to the dynamic type of the object it's invoked on.
inline means that you're allowed to define the function in more than one translation unit, and must define it in any translation unit that uses it. This is necessary (for some compilers) to allow the function to be inlined, but does not force all calls to be inlined. In particular, virtual calls usually won't be inlined (unless the dynamic type can be determined at compile time), so virtual will certainly retain its meaning here.
Is this considered to be an inline?
Yes, but (as mentioned above) that does not mean that all calls will be inlined.
Is the virtual functionality meaningless because the function is
implemented in the .h?
Nope. No reason to feel so. Header file is preprocessed and copy-pasted wherever it's included. So ultimately it's as good as implementing your g() in whatever .cpp file.
Is this considered to be an inline?
Yes. But here the inline doesn't mean usual interpretation of replacing function call with its content. virtual function resolution happens at runtime, so that can definitely not be inlined in that (macro style) way.
It means, that compiler guarantees to generate only 1 definition for all translation (.cpp file) units. Thus linker will not complain about multiple definition errors.
If you declare your function virtual, it is virtual, period. But, since virtual functions are usually selected at runtime, usually the compiler will not be able to inline them. If you call the function on an object, the compiler may inline it, since the call can be resolved at compile time. But it won't be able to inline a call through a reference or pointer, since it cannot resolve the dynamic type at compile time.
Take into account that neither the inline keyword not the implicit inlining here are mandatory for the compiler; they are just suggestions. But the virtual keyword is mandatory.
Related
When I write wrapper classes, a lot of the methods take the following form:
class Wrapper{
public:
vec3 getPos(){ return m_position.get(); }
void setPos(vec3 pos){ m_position.set(pos); }
private:
ThingGettingWrapped m_position;
}
}
I was curious however, will getPos() and setPos() incur overhead, or are modern compilers smart enough to optimize the delegation away so wrapper.set/get() is equivalent to wrapper.m_thingWrapped.set/get()?
(I know the methods are inlined in my example, but assume they are not explicitly inlined and defined separately)
An optimizer can expand the call inline in which case there is no overhead for the extra call.
A wrapper like that can incur overhead if the call is not expanded inline.
Optimizers of modern compilers do inline expansion.
assume they are not explicitly inlined and defined separately
There will be (small) overhead unless the optimizer can expand the call inline. You can guarantee the ability to inline by calling the function in the same translation unit where it was defined. Defining the function inline - like you did in your example - enables and enforces this for all translation units because inline functions are defined in all of them. Another way to allow inline expansion across translation units is LTO.
A function is not required to be inline in order for it to be expandable inline and an optimizer is not required to inline-expand all calls to inline functions. A function that is inline will always be expandable inline. A function that is not inline may be expandable in some case, but not always.
These functions will get inlined by the compiler as long as some simple rules are followed:
They are not virtual (they aren't in your case, but could be in some other place) - compiler often can't inline virtual functions - because it would render the whole idea of virtual functions useless.
The actual implementation of the function is available to the compiler during the compilation of the source calling getPos. Again, it would not be possible to compile the example code, but you could declare getPos and setPos as member functions without giving them a body in the class, in which case the compiler won't (necessarily) be able to inline them. [1]
[1] Compilers that support Link Time Optimisation (LTO) or Whole Program Optimisation as some compiler vendors like to call it can inline functions even if the source is not available - this is because final code-generation isn't done until later, so a half-compiled version of the source is stored in the object file. In my experience, LTO is not used for most projects.
I recently decided to use the non-virtual interface idiom (NVI) to design an interface in C++, mostly for the purpose of using a parameter with a default value (thus avoiding problems caused by the fact that default parameters are statically bound).
I came with a rather trivial declaration for my class, looking like this :
class Interface{
public:
void func(Parameter p = 0);
virtual ~Interface();
private:
virtual void doFunc(Parameter p)=0;
};
void Interface::func(Parameter p){ doFunc(p); }
Interface::~Interface() {}
I know that providing the function body in a header automatically mark a function as candidate for inlining (though I don't know if placing the definition outside of the class will prevent that). I also know that virtual function aren't inlined for obvious reasons (we don't know which function will be called at runtime, so we can't replace calls by the function's body obviously).
Then, in this case, will func() be marked candidate for inlining ? It isn't a virtual function, but still calls a virtual function. Does it make it inline-able ?
Extra question: would it be worth it ? The body consist of only one statement.
Note that this question is quite rather for learning about it rather than searching optimization everywhere. I know that this function will be called only a few time (well, for now, so might as well be prudent as to how the program evolves), and that inlining would be quite superfluous and not the main concern about my program's performance.
Thanks !
I know that providing the function body in a header automatically mark a function as candidate for inlining
More or less; but you do that by providing the function body in a class definition, or by explicitly declaring it inline if it's in a header. Otherwise, the function is subject to the One Definition Rule, and you'll get errors if you include the header in more than one translation unit.
Note that this doesn't force the compiler to inline all calls to the function; providing the definition in a header just allows it to inline it in any translation unit that includes the header, if it thinks it's worth it. Also, some compilers can perform "whole program optimisation", and inline functions even when a definition is not available at the call site.
Then, in this case, will func() be marked candidate for inlining ? It isn't a virtual function, but still calls a virtual function. Does it make it inline-able ?
Yes, all functions are candidates for inlining. If they call themselves, then obviously you couldn't inline all the calls; nor if the function isn't known at compile time (e.g. because it must be called virtually, or through a function pointer). In this case, inlining the function would replace the direct call to func() with a virtual call to doFunc().
Note that sometimes virtual calls can be inlined, if the dynamic type is known at compile time. For example:
struct MyImplementation : Interface {/*whatever*/};
MyImplementation thing;
thing.func(); // Known to be MyImplementation, func and doFunc can be inlined
Extra question: would it be worth it ?
That depends on what "it" is. If you mean compile time then, as long as the function remains short, you might get some benefit (possibly significant, if the function is called many times) for negligible cost. If you mean the cost of spending time choosing where to put it, then probably not; just put it wherever's most convenient.
Under What condition an inline function ceases to be an inline function and acts as any other function?
The Myth:
inline is just a suggestion which a compiler may or may not abide to. A good compiler will anyways do what needs to be done.
The Truth:
inline usually 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(especially w.r.t One Definition Rule) for inline are followed.
Under What condition an inline function ceases to be an inline function and acts as any other function?
Given the quoted fact there is a deeper context to this question.
When you declare a function as static inline function, the function acts like any other static function and the keyword inline has no importance anymore, it becomes redundant.
The static keyword on the function forces the inline function to have an internal linkage.(inline functions have external linkage)
Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals(an inline function has only one copy of these ).
It's at the discretion of the compiler.
But some cases just can't be inlined, like:
Recursive functions
Functions whose address is referenced somewhere
Virtual functions (there are some exceptions thought)
That depends on the compiler optimization.
Different compilers have different rules to make the code more efficient. But if you declare a function as inline, the compiler tends to respect your decision as long as none of it's rules says different.
Remember that the compiler can change completely the execution path of a method. For example, consider the next situation:
int MyClass::getValue()
{
return someVariable;
}
At compile time, there is little difference between declaring this kind of function as inline or not. Probably the compiler will make the attribute partially public and code:
myInstance->getValue()
as
myInstance->someVariable
So it's more an aesthetical decision in most cases.
From what I read somewhere long time ago, it seems that if you want class member function to be inlined during the compilation phase, the function has to be defined inside class declaration block.
But this has a downside of a detail leak. IMHO, other programmers should only see class interface when opening .h file.
Is the first statement still true in modern C++, was it ever? Is there a way to force inlining for functions that are declared, preferably in another file altogether?
Is it generally better to keep short member functions inside class declaration block, or not?
It seems that if you want class member function to be inlined during the compilation phase, the function has to be defined inside class declaration block.
That is not really true. A function that is defined inside the class definition is implicitly marked as inline. But you don't need to defined the function inside the class for it to be inline, you can explicitly request it:
struct X {
void f();
};
inline void f() {}
The inline keyword on the other hand, does not mean that the function will be inlined, but rather that it can be defined in multiple translation units, that is, if multiple translation units include the same header that contains that definition, the linker will not fail with a multiple definition error.
Now, on actual inlining, the compiler can decide to inline or not any function, regardless of whether the function is declared as inline provided that it sees the definition of that function (the code that it will inline), which is the reason why in general functions that are meant to be inlined should be defined in the header (either inside the class definition or marked inline outside.
Additionally, newer toolchains can perform whole program optimization or other link time optimizations, by which the linker can also decide that a function should be inlined. In this case, the function definition needs not be visible at the call site, so it could be defined inside the .cpp file. But if you really want the function to be inlined it is better not to depend on this feature and just define the function in the header.
Q: Is there a way to force inlining for functions?
A: No
No matter how you designate a function as inline, it is a request that
the compiler is allowed to ignore: it might inline-expand some, all,
or none of the calls to an inline function.
Q: What are the inlining rules within C++ classes?
Inline member functions in C++
As far as Standard C++ is concerned, a inline function must be defined
in every translation unit in which it is used
...
This is different from non-inline functions which must be defined only
once in an entire program (one-definition-rule)...
For member-functions, if you define your function in the class, it is
implicitly inline. And because it appears in the header, the rule that
it has to be defined in every translation unit in which it is used is
automatically satisfied.
Here is a great FAQ (one that's more "practical" than "pedantic"):
http://www.parashift.com/c++-faq-lite/inline-functions.html
Is the first statement still true in modern C++, was it ever?
As David explained, there's the inline keyword as well. It can be ignored, as Paul stated.
Is there a way to force inlining for functions that are declared,
preferably in another file altogether?
Probably by configuring your compiler. It might be doing some inling behind your back anyway. Eg. gcc has -finline-functions etc. that will be switched on for certain optimisation levels
Is it generally better to keep short member functions inside class declaration block, or no?
Up to you. Be aware though that if you have an inline method used lots of times, then you can be increasing the size of your object files, and so potentially bloat the size of what you're building and maybe slow it down.
FWIW I only tend to put implementations in header files out of laziness :)
I think my question has been asked here before, I did read them but still little confused and therefore asking to make it clear.
The C++ standard says all member functions defined inside class definition are inline
I have also heard that compiler can ignore inlining of a function. Will that be true in the above case or it will be always inlined if defined inside class definition?
Also, what was the reason behind this design, making all functions defined inside class definition inline? And what inlining has to do with source and header files?
Update: So one should always define their functions outside class if not to be inlined, right?
Update 2 by JohnB: Two functions declared inside class definition could never call each other as they would have to each contain the whole body of the other function. What will happen in this case? (Already answered by Emilio Garavaglia)
Confusion arises because inline has two effects:
It tells the compiler that the function code can be expanded where the function is called, instead of effectively being called.
It tells the compiler that the function definition can be repeated.
Point 1. is "archaic" in the sense that the compiler can in fact do what it likes in order to optimize code. It will always "inline" machine code if it can and find convenient to do and it will never do that if it cannot.
Point 2. is the actual meaning of the term: if you define (specify the body) a function in the header, since a header can be included in more sources, you must tell the compiler to inform the linker about the definition duplicates, so that they can be merged.
Now, by the language specification, free functions (not defined in class bodies) are by default not defined as inline, so defining in a header a thing like
void myfunc()
{}
if the header is included in more sources, then linked in a same output, the linker will report a multiple definition error, hence the need to define it as
inline void fn()
{}
For class members, the default is the opposite: if you just declare them, they will not be inlined. If you define them, they will be inline.
So a header should look like
//header file
class myclass
{
public:
void fn1()
{} //defined into the class, so inlined by default
void fn2();
};
inline void myclass::fn2()
{} //defined outside the class, so explicit inline is needed
And if myclass::fn2() definition goes into a proper source, must lose the inline keyword.
The inline keyword has for a function 2 meanings:
Code replacement: Wherever inline function is invoked, don't generate a function call for it but simply place the contents of the function
at the place of its call (this is something similar to macro
replacement, but type safe)
One definition rule: Don't generate multiple definition for a inline function, only generate a single definition common for all (exception: static functions)
The 1st terminology ("Code replacement"), is simply a request to the compiler. which can be ignored as compiler is better to judge whether to put the text or a function call. (for example, virtual functions or recursive functions cannot be inlined).
The 2nd terminology ("One definition rule") is guaranteed to happen by any conforming compiler. This will generate only 1 definition for all translation units. This facility eases coder's work sometimes, as for smaller function one may not want to put its definition in .cpp file (e.g. getters, setters).
Moreover, for template function which are header only constructs, this effect is mandatory. Thus template functions are inline by default.
Examples:
class A {
public:
void setMember (int i) { m_i = i; }
};
In this example mostly compiler would suffice both terminologies
class A {
inline virtual ~A () = 0;
};
A::~A() {}
Here compiler can only suffice the 2nd requirement.
The only reason to make the method function inline is if you define it in the header.
If you define a method function in a header, and you do not put inline keyword, and you include the header in several header or source files, you would get multiple definition of the method.
c++11 standard in 9.3/2 Member functions [class.mfct] tells :
A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2) ...
When the definition is inside the class, it is treated as if it were declared inline, because it is assumed that class definitions live in header files that are used from more than one translation unit, so any non-inline definitions here would violate the One Definition Rule.
The compiler is, as always, free to inline whatever it thinks as long as it takes care that functions that are either explicitly or implicitly inline will not lead to linker errors. How it does that is left open by the language spec -- inlining the function of course works, but it is also acceptable to demote the symbol visibility or rename the symbol to a translation unit specific name (as if the function were in an anonymous namespace), or (as most of them do) communicate to the linker that multiple copies of that function may exist and that it should discard all but one of them.
So, in short, it is not treated any different from functions that are explicitly declared inline.
The compiler can ignore inlining if specified by the inline keyword. If the method implementation is present inside the class definition, that's a different thing, and can't be ignored. (well it can, but that makes the compiler non-conforming)
The reason behind the desing - I'm assuming a mechanism was needed where you can actually force the compiler to actually inline your functions, since the inline keyword doesn't mandate it. But in general, inline method definition is done only in cases like getter and setter methods, or some trivial 2-liners. And templates, but that's a different issue.
Inlining has to do with headers and source files in that the definition of the function must be visible to the compiler so it knows how to actually inline the call. It's more difficult to inline a function defined in an implementation file than one defined in a header.
EDIT: On a side note, the paragraph the op is reffering to is 7.1.2.3:
A function defined within a class definition is a inline function [...].
EDIT2:
Apparently, there are some difference between an inline function and inline substitution. The first is a property of a function, that doesn't only include inline substitution, the second means that the function body is actually pasted where it is called.
So the function can be inlined but not have its body pasted instead of being called.
the two things you reffer to are different aspects and not to be confused with.
1) The C++ standard says all member functions defined inside class definition are inline
2) I have also heard that compiler can ignore inlining of a function
1) is when you define the member functions inside the class declaration itself. ie: in the header files. for that you do not have to provide any keyword( ie: inline)
2) You can specify a function as inline by explicitly using the inline keyword. this is actually a request to the compiler. the compiler may or may not make the function inline according to some rules of optimization.