I'm reading a C++ tutorial and I've ran into this sentence:
The only difference between defining a class member function
completely within its class or to include only the prototype and later
its definition, is that in the first case the function will
automatically be considered an inline member function by the compiler,
while in the second it will be a normal (not-inline) class member
function, which in fact supposes no difference in behavior.
I know what an inline function is, my doubt is about which style to choose. Should I define every function inside its class or outside? Perhaps the simplest functions inside and the other outside?
I fear that defining every function inside a class (i.e. having complex inline functions) might mess up the resulting code and introduce debugging problems or weird behaviors during execution. And, finally, there's the "coding style" issue. So,
which approach is better?
Thank you :)
My style: I sometimes will put extremely short (one or two liner) functions in the class itself. Anything longer that I still want as an inlined function go as inline qualified implementations after the class definition, and oftentimes in a separate file that the header #includes at the end of the class definition.
The rationale for putting an inlined function outside the class is that the implementation of some function usually just gets in the way of a human reader's overall understanding of the class. A twenty line function can usually be summarized in a one line comment -- and that comment is all that is needed when you are reading the class definition. If you need more, go to the function definition, or better yet, Read The Fine Documentation. (Expecting someone to Read The F*** Code is a poor substitute for Fine Documentation.)
The best solution is to separate interface and implementation. Interface is your h-file. Put only prototypes there. Implementation goes to cpp-file. This approach has the following advantages:
Compilation goes faster because there is no need to compile function bodies several times.
Header dependency is simpler because there is no need to include all headers to h-file. Some of the headers are needed only in cpp-file and you can use forward declarations in h-file. Also you can avoid circular dependencies.
The last but not the least - it is easier for human beings to understand interface of your class. There is no code mess.
To answer the part of "Which approach is better?" - From C++ FAQ -
There are no simple answers: You have to play with it to see what is best. Do not settle for simplistic answers like, "Never use inline functions" or "Always use inline functions" or "Use inline functions if and only if the function is less than N lines of code." These one-size-fits-all rules may be easy to write down, but they will produce sub-optimal results.
Neither approach is better per se its a matter of preference and style. Personally I always think that defining the functions explicitly in a seperate .inline file is the best way. This way you are very explicit over what you do and you keep the header file clean.
Furthermore if you use a macro such as INLINE which is defined as follows:
#ifdef DEBUG
#define INLINE
#else
#define INLINE inline
#endif
You can then include the inline file from the header in release and from the CPP in debug. This means that even if the compiler inlines functions in debug you won't have any difficulties when debugging. Admittedly, though, this isn't such a problem for compilers these days so you may want to skip doing this unless using an old compiler.
Generally speaking, a member function which has only one or two statements is probably best with its body written in the class declaration—especially if there are many of them. A member function with more than 20-50 statements is probably best not in the class declaration. For lengths and complexities between, it depends on many factors.
For example, having the function body in a class module helps prevent unnecessary recompiling of dependent modules when the class declaration does not change—only a member function body. This can greatly increase productivity when developing the class. Once the class is stable, this becomes much less important.
Related
What is the best use of function proto-typing in c++?
For instance I understand you can use it to place functions below the scope of your 'main' function. When is this considered useful?
I always like to have my main at the bottom of the main file as a personal preference.
I do not have a whole lot of experience with C++ and trying to get better with it.
I did notice that it seems to have a quicker execution time if you do not proto type.
By far the most useful effect of having function prototypes is that you don't need to put all your function definitions in their respective headers. If this was the case, compile time would go through the roof!
Another important case where it's necessary is when two function implementations have a cyclical dependency on one another. Putting these cyclical dependent definitions after both functions have been declared makes this possible. This is sometimes necessary even for function templates.
I'm new in c++ world, and learned that it is a good practice to make forward declarations. But is it always good?
I'm looking for guidelines for when it is a good practice to make a forward declaration and when it is not good, but I really couldn't find any. There are any objective case for when it should be used or not, or it is entirely up to the developer?
There can be cases where you actually start complicating your code base with otherwise unnecessary applications of the PIMPL idiom (which involves forward declarations) to reduce compilation time when in fact you do not have any compilation speed problems in the first place, at least with that particular class or header file.
This can then be considered a case of premature optimisation and a misuse of forward declarations.
As mentioned by juanchopanza, in general you can use forward declarations when you don't need a full class definition - basically when you don't need to know the size or members of the class in question. It allows you to remove compile-time dependencies, which can simplify and speed-up compilations.
For example, if you only use pointers to a class, then you don't need to know any more about it. However, if you call a method of that class, or store an actual instance of it, then you need to know the full details of the class.
class A; // forward declaration
class B {
...
void func1(A*);
}
class C {
...
A m_inst;
}
In the above, C will not compile, as it needs to know the size of A at the point of declaration. However, func1 is fine, as it only uses a pointer to A, so doesn't need to know size or implementation.
Herb Sutter has a bit of information along with explanations, although be warned that some of it is a little advanced if you're a beginner.
If I have a C++ template I have two choices (without the export keyword) to link them:
Inclusion model with inlining - i.e. including the definitions together with the declarations in the .h file. This inlines all the functions and create a big unit (although it's lazy)
Inclusion model without inlining - i.e. something like including this .h file:
code:
// templateinstantiations.cpp
#include "array.cpp"
template class array <int, 50>; // explicit instantiation
every time I want to use a template, and being careful to explicit instantiating every single type I need (this can be boring and hard to maintain)
My question is: I know that excessively inlining functions may cause memory thrashing and losses of performances.. besides it seems that in both the above cases compilation times are huge.. what is the tradeoff between the first and the second approach? Is there a criterion to choose the first over the second or I just need to try them out and "time" them?
This question isn't really about templates but about inlining, I think. For the purposes of run-time performance, the compiler probably does the right choice in most cases: if it can see that a function is too big to benefit from inlining it is likely to generate a non-inlined version of any inline function, independently of the function being a template or not. Each translation unit will create its own version of the function and the linker will choose one to use (and, hopefully, throw away the other unused copies but whether it really does this depends on the linker and the object file format).
The interaction with templates comes in when looking at the various interactions between the template code and the functions it calls which may be templates themselves: When forcing the code not to be inlined, the compiler has no chance to avoid the overhead of a function call. Often the abstractions used by templates are very simple functions, e.g., "increment an iterator" and "dereference an iterator" mapping to underlying pointer operations, creation a function call can become rather expensive due to the function call overhead and the lost opportunity for optimizations. However, the compiler can actually see through this and do the right choices in many cases.
That said, I'm a big fan of creating explicit instantiations for certain templates. For example, removing certain parts of the IOStreams library from the headers and explicitly instantiating it in the library has a huge effect on compile time, especially when optimization is turned on: Calling a simple output function for an integer causes lots of templates to be instantiated. Putting this code into its own file and compiling it with the appropriate optimization options probably won't make much of a difference with respect to performance but it does have a major effect on compile times. This may have an indirect impact on performance, though: you can afford more iterations testing the performance of the code using the library.
Even when you explicitly declare a function as inline there is no guarantee that C++ make it inline, so how you think that implementing a template all in header will force an inline implementation and cause you some problems?
In almost all cases you don't need second case although you can do like that but it is not needed to avoid inline problems
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 :)
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.