inline this function, does make sense? - c++

I have the next member function:
template <typename T>
inline T Foo::Read(const DWORD addr) const // Passing by value.
{
T buffer;
ReadProcessMemory(m_processHandle, (LPVOID)addr, &buffer, sizeof(T), NULL);
return buffer;
}
If I'm not wrong, when the compiler inlines a function, it avoids calling the function and put the code of the called function into the caller function.
So in the caller function (assuming an integer return type) I would want something like:
ReadProcessMemory(m_processHandle, (LPVOID)addr, &bufferOfTheCaller, sizeof(int), NULL);
I have three questions about this:
1) What would happen with the variable that we return from the function?
Isn't the declaration of the variable buffer performed in run time?
2) In this case ReadProcessMemory is a huge function from the WinAPI, should the compiler still able to inline this function?
3) What is the difference between leaving the member function defined inside the class definition and declare it with the keyword inline outside the class definition? If I want to use inline keyword, Do I have to put the inlined function in the same file .h or?

It's important to note that the inline keyword has nothing to do with inlining calls to the function. All it does is allow the function to be defined in multiple translation units, as long as all of the definitions are the same.
What the inline keyword does is let you define a function in a header file that will be included in multiple translation units. This may give the compiler a better opportunity to inline call to that function, since it has the full definition available in multiple translation units, but it is not a command or even a hint that you want the compiler to do so. The compiler will decide on its own if it should or shouldn't inline a call to any given function. There are compiler-specific extensions that you can use if you do want to force calls to a function to be inlined, but that is not what the inline keyword does.
With that out of the way, I'll add that the compiler inlining a function call doesn't change the rules of C++ at all. It isn't a textual replacement, like a preprocessor macro. The compiler will figure out how to insert the logic from the called function into the caller. At that point, things like C++ variables don't really exist. If your call looks something like this:
int someValue = myFoo.Read(someAddress);
then the compiler can easily transform that into something like this:
int someValue;
ReadProcessMemory(myFoo.m_processHandle, (LPVOID)someAddress, &someValue, sizeof(int), NULL);
due to the as-if rule. Both of those snippets result in the same observable behavior, so the compiler can freely transform between them.

What would happen with the variable that we return from the function?
It will be destroyed, because the return value was discarded by the function call expression.
Isn't the declaration of the variable buffer performed in run time?
Declarations happen at compile time.
In this case ReadProcessMemory is a huge function from the WinAPI, should the compiler still able to inline this function?
If the compiler knows the definition of the function, then it could expand it inline. Whether it should, or whether it will do so depend on many factors. Size of a function is a heuristic that may affect the choice that the compiler makes.
What is the difference between leaving the member function defined inside the class definition and declare it with the keyword inline outside the class definition?
In one case the definition is inside the class and in the other case it is outside. There is no other difference.
If I want to use inline keyword, Do I have to put the inlined function in the same file .h or?
If you want to define a member function inline, but want to define it outside of the class definition, then you must declare the function inline within the class definition - except a function template, which is implicitly inline.
If you want to define the member function within the class definition, then you don't need to explicitly declare it inline; it will be so implicitly.
If you want to not define the function inline, then you must define the function outside the class definition and must not use the inline keyword.

If I'm not wrong, when the compiler inlines a function, it avoids calling the function and put the code of the called function into the caller function.
Yes, but inline has little to do with that.
1) What would happen with the variable that we return from the function? Isn't the declaration of the variable buffer performed in run time?
The compiler, inlining or not, will have to reserve some space for buffer, typically on the stack.
In other words, there is no bufferOfTheCaller. If your function is inlined, buffer will be in the caller's stack frame; otherwise, it will be put in the callee's stack frame.
2) In this case ReadProcessMemory is a huge function from the WinAPI, should the compiler still able to inline this function?
It does not matter how big the implementation of ReadProcessMemory is, your code just performs a function call to it, which is tiny. An optimizing compiler is likely to inline your function.
3) What is the difference between leaving the member function defined inside the class definition and declare it with the keyword inline outside the class definition?
No difference.
If I want to use inline keyword, Do I have to put the inlined function in the same file .h or?
The inline keyword is not about inlining. If you want to put the definition of a function in a header file, you will likely need inline to prevent redefinition errors.

Related

Inline Functions, inside class, C++

I have read, multiple times, that all member functions defined inside a class are inlined by default. Does that mean that the compiler will always put the body code of the function on the stack if it is suitable( i.e. the code does not contain any loops or function calls)?
all member functions defined inside a class are inlined by default.
No, they are inline by default.
That means that the definition can and must be provided in every translation unit where the functions are used. For member functions that means, where an instance of the class is used.
inline also has a hinting effect about machine code inlining of calls. The compiler can follow or ignore that hint at its discretion, per call.

Inline functions in c++ - conditions

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.

What are the inlining rules within C++ classes?

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

Why are class member functions inlined?

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.

inline in definition and declaration

During a recent peer review, another Software Engineer suggested that I state that the inline function is inline in the definition (outside of the class) as well as in the declaration (inside of the class). His argument is that "By marking it inline, you are saying that this method will be executed much faster than a non-inline method, and that callers don't have to worry about excessive calls to the method."
Is that true? If I am a user of a class, do I really care about excessive calls to the method? Is there anything wrong with listing it as inline in both the definition and declaration? The C++ FAQ states:
Best practice: only in the definition outside the class body.
So who is right here?
That sounds like two totally unrelated things. Putting inline at both the declaration in the class and the definition outside of the class is not needed. Putting it at one of the declarations is enough.
If you talk about adding inline in a .cpp file where a function is defined there, and that function is a public member, then you should not do that. People who call inline functions must have their definitions visible to them. The C++ Standard requires that.
By marking it inline, you are saying that this method will be executed much faster than a non-inline method, and that callers don't have to worry about excessive calls to the method.
That's nonsense. Marking a function inline doesn't guarantee that the function will actually be physically inlined; even if it is, that's no guarantee that your function will be "faster".
By marking the definition inline as well as the declaration, you're just confusing things by pretending to your user that there's any guarantee about anything, which there isn't...
If I am a user of a class, do I really care about excessive calls to the method?
Not really.
In fact, really, the only time you should write inline is when you need to force inline storage for some reason (regardless of whether inlining occurs, using the keyword always affects the application of the one-definition rule to your function… though requiring this is rare); otherwise, let the compiler decide which functions to inline, and move on. The corollary of this is that you don't need to worry about using the keyword to pretend that it's documenting anything.
A function definition defined in the header file should use the inline specifier.
example double get_f(){return f;} defined in foo.h
should use the inline specifier as in:
inline double f_get{return f};
According to the C++ guidelineS.
As for inlining outside the header I have not seen any information that would suggest it is needed.