Consider this:
class Foo{
void func1(){
/*func1 code*/
}
void func2(){
/*func2 code*/
}
};
Case 1: class Foo in Foo.h
Case 2: class Foo nicely seperated among Foo.h and Foo.cpp
Various other cpp files include Foo.h
My question is...Will Case 1 lead to a bigger binary?
Maybe it will, maybe it won't. It really has nothing to do with header files. What matters here is that your member functions are defined in the class definition. When member functions are defined like that, they are treated as inline functions. If the compiler decides not to actually inline any calls to these functions, there won't be any impact on code size. If the compiler decides to inline any (or all) of the calls, the answer would be "it depends". Inlining calls to small functions might result in increased code size as well as in decreased code size. This all depends on the function itself and on the compiler's capabilities (optimization capabilities specifically).
If compiler decides not to inline those functions, and generate separate body for them, these bodies will appear in each object file who uses them, but with special flag for linker - 'weak symbol'. When linker finds this flag, it will combine all symbols with that name into only one resulting symbol (maybe it will produce error message if bodies or sizes of such symbols are different)
Also RTTI info and vtables also use same scenario.
With dynamic libraries, weak symbol joining may happen at run-time, if they uses the same class.
If the functions in the header are declared as static, than yes, each module (source file) that includes that header file will store a copy of that function in the object file and the final executable will be bigger in size...
If you have the code definition in the header, the compiler might create redundant copies of each function whenever you include the .h. Those redundant copies might also trigger errors from the linker, so the practice is generally frowned upon except for inline functions.
If the code for functions is included inline in the headers, then the compiler can use that to define the functions in the object code for each separate source file, or embed the function code directly where the functions are called. Depending on your compiler and linker and the support for C++ generally, that may leave you with larger code than you would have with the functions all defined separately. If the inline functions are small enough, you may save space by avoiding function call overhead. However, such functions have to be very small.
Related
Background: The C++ inline keyword does not determine if a function should be inlined.
Instead, inline permits you to provide multiple definitions of a single function or variable, so long as each definition occurs in a different translation unit.
Basically, this allows definitions of global variables and functions in header files.
Are there some examples of why I might want to write a definition in a header file?
I've heard that there might be templating examples where it's impossible to write the definition in a separate cpp file.
I've heard other claims about performance. But is that really true? Since, to my knowledge, the use of the inline keyword doesn't guarantee that the function call is inlined (and vice versa).
I have a sense that this feature is probably primarily used by library writers trying to write wacky and highly optimized implementations. But are there some examples?
It's actually simple: you need inline when you want to write a definition (of a function or variable (since c++17)) in a header. Otherwise you would violate odr as soon as your header is included in more than 1 tu. That's it. That's all there is to it.
Of note is that some entities are implicitly declared inline like:
methods defined inside the body of the class
template functions and variables
constexpr functions and variables
Now the question becomes why and when would someone want to write definitions in the header instead of separating declarations in headers and definitions in source code files. There are advantages and disadvantages to this approach. Here are some to consider:
optimization
Having the definition in a source file means that the code of the function is baked into the tu binary. It cannot be inlined at the calling site outside of the tu that defines it. Having it in a header means that the compiler can inline it everywhere it sees fit. Or it can generate different code for the function depending on the context where it is called. The same can be achieved with lto within an executable or library, but for libraries the only option for enabling this optimization is having the definitions in the header.
library distribution
Besides enabling more optimizations in a library, having a header only library (when it's possible) means an easier way to distribute that library. All the user has to do is download the headers folder and add it to the include path of his/her project. In the case of non header only library things become more complicated. Because you can't mix and match binaries compiled by different compiler and even by the same compiler but with different flags. So you either have to distribute your library with the full source code along with a build tool or have the library compiled in many formats (cpu architecture/OS/compiler/compiler flags combinations)
human preference
Having to write the code once is considered by some (me included) an advantage: both from code documentation perspective and from a maintenance perspective. Others consider separating declaration from definitions is better. One argument is that it achieves separation of interface vs implementation but that is just not the case: in a header you need to have private member declarations even if those aren't part of the interface.
compile time performance
Having all the code in header means duplicating it in every tu. This is a real problem when it comes to compilation time. Heavy header C++ projects are notorious for slow compilation times. It also means that a modification of a function definition would trigger the recompilation of all the tu that include it, as opposed to just 1 tu in the case of definition in source code. Precompiled headers try to solve this problem but the solutions are not portable and have problems of their own.
If the same function definition appears in multiple compilation units then it needs to be inline otherwise you get a linking error.
You need the inline keyword e.g. for function templates if you want to make them available using a header because then their definition also has to be in the header.
The below statement might be a bit oversimplified because compilers and linkers are really complex nowadays, but to get a basic idea it is still valid.
A cpp file and the headers included by that cpp file form a compilation unit and each compilation unit is compiled individually. Within that compilation unit, the compiler can do many optimizations like potentially inlining any function call (no matter if it is a member or a free function) as long as the code still behaves according to the specification.
So if you place the function definition in the header you allow the compiler to know the code of that function and potentially do more optimizations.
If the definition is in another compilation unit the compiler can't do much and optimizations then can only be done at linking time. Link time optimizations are also possible and are indeed also done. And while link-time optimizations became better they potentially can't do as much as the compiler can do.
Header only libraries have the big advantage that you do not need to provide project files with them, the one how wants to use that library just copies the headers to their projects and includes them.
In short:
You're writing a library and you want it to be header-only, to make its use more convenient.
Even if it's not a library, in some cases you may want to keep some of the definitions in a header to make it easier to maintain (whether or not this makes things easier is subjective).
to my knowledge, the use of the inline keyword doesn't guarantee that the function call is inlined
Yes, defining it in a header (as inline) doesn't guarantee inlining. But if you don't define it in a header, it will never be inlined (unless you're using link-time optimizations). So:
You want the compiler to be able to inline the functions, if it decides to.
Also it may the compiler more knowledge about a function:
maybe it never throws, but is not marked noexcept;
maybe several consecutive calls can be merged into one (there's no side effects, etc), but __attribute__((const)) is missing;
maybe it never returns, but [[noreturn]] is missing;
...
there might be templating examples where it's impossible to write the definition in a separate cpp file.
That's true for most templates. They automatically behave as if they were inline, so you don't need to specify it explicitly. See Why can templates only be implemented in the header file? for details.
As far as I know it's impossible to have a function declared as "inline" in a lib file and have that function "magically inlined" into a caller function into another project (since linking is not the same as compiling and the latter happens before).
How could I inline a function when having multiple functions (into multiple libraries) that have the same declaration but different definition?
e.g.
obj1.lib
void function1() { printf("Hi"); }
obj2.lib
void function1() {printf("whatsup?"); }
main.cpp
void function1();
int main()
{
function1(); // I'd like to be able to inline this, I can steer the linking against obj1 or obj2, but I can't inline this one
}
To inline a function from an object (or a library) file you'll need this object file be compiled with link-time optimization (LTO). See Inlining functions from object files for more details.
Even if you inline functions, they always have to have the same definition: having different defintions for the same entity in a C++ program is a violation of the one definition rule (ODR) specified in 3.2 [basic.def.odr]. ODR violations are often not detected by compilers and linkers and tend to result in rather weird problems.
You'll need to make sure the functions are different, e.g., using one of these techniques:
Give them a different name.
Put the functions into a namespace.
Give the functions a different signature.
Make the static to have them visible only in the given translation units.
The simplest you can do is to give the functions different names.
If you want built-time selection of a function with a given name, that has 2 or more different implementations, and you want to support machine code inlining of that function, then declare it as inline, which requires also supplying the implementation in each variant's header, and use include and lib paths to select the relevant header (for compilation) and lib (for linking) – they'd better match. As with any inline function this doesn't guarantee machine code inlining. With respect to machine code inlining inline is just a hint (it's guaranteed effect is about permitting a definition in each translation unit, and requiring such a definition in each translation unit where it's used).
How to use include and lib paths depends on your toolchain.
Edited in response to Sam Cristall's comment.
If you mean "inline at compile time" then:
In order to use a library you need to include the header file(s) associated with that library. If the desired function is declared inline in that header and the function definition (the body of the function) is available, then the compiler will (at it's discretion) inline the function. Otherwise it won't.
If you mean "inline at link time" (an unfortunate overloading of the word "inline") than see the other answers
Is there any difference between inline member function (function body inline) and other normal member function (function body in a separate .cpp file)?
for example,
class A
{
void member(){}
};
and
// Header file (.hpp)
class B
{
void member();
};
// Implementation file (.cpp)
void B::member(){}
There is absolutely no difference.
The only difference between the two is that the member inside the class is implicitly tagged as inline. But this has no real meaning.
See: inline and good practices
The documentation says that the inline tag is a hint to the compiler (by the developer) that a method should be inlined. All modern compilers ignore this hint and use there own internal heuristic to determine when a method should be inlined (As humans are notoriously bad and making this decision).
The other use of inline is that it tells the linker that it may expect to see multiple definitions of a method. When the function definition is in the header file each compilation unit that gets the header file will have a definition of the function (assuming it is not inlined). Normally this would cause the linker to generate errors. With the inline tag the compiler understands why there are multiple definitions and will remove all but one from the application.
Note on inlining the processes: A method does not need to be in the header file to inlined. Modern compilers have a processes a full application optimization where all functions can be considered for inlining even if they have been compiled in different compilation units. Since the inline flag is generally ignored it make no difference if you put the method in the header or the source file.
Ignore the word inline here and compiler hints because it is not relevant.
The big practical difference in A and B is when they are used in different libraries.
With the case of A you can #include the header and are not required to link against anything. So you can use this class from different applications / libraries without any special linkage.
With the case of B, you need B.cpp and this should be compiled only into one library / application. Any other library or application that needs to use this class will need to link against the one that contains the actual body of the code.
With some setups / implementations you will need to specifically mark the class as "exported" or "imported" between libraries (for example with Windows you can use dllimport / dllexport and with GNU you can use attribute(visibility="default") )
The first one is implicitly inline, i.e. suggesting the compiler to expand it at the call site.
Other than the inline thing, there's a difference in that you could put more definitions in between the definition of class B, and the definition of the function.
For example, B.cpp might include header files that B.hpp doesn't, which can make a significant difference to the build process for large projects.
But even without a separate translation unit, you can occasionally have a circular dependency that's resolved by separating the definitions. For example the function might take a parameter of a type that's forward-declared before B is defined, then defined by the time the function is defined. If that type uses the definition of B in its own definition, it can't just be be defined before B.
I just learned that defining a c++ function inside a class's header file make the function inline. But I know that putting the inline keyword next to a function is only a suggestion and the compiler wont necessarily follow it. Is this the same for header defined c++ functions and is there a difference in behavior between a standalone c++ function and a c++ function that is part of a class?
"defining a c++ function inside a class's header file make the function inline"
That's not true. Defining a function (that is to say, providing the body of the function instead of just a declaration) inside a class definition makes it inline. By "makes it inline", I mean it's the same as giving it the inline keyword. But class definitions don't have to be in headers, and headers can contain other things than class definitions.
So in this example, the function foo is implicitly inline. The function bar is not implicitly inline:
struct Foo {
void foo() {}
void bar();
};
void Foo::bar() {}
"putting the inline keyword next to a function is only a suggestion and the compiler wont necessarily follow it"
inline has two effects. One of them is a hint to the compiler which it can ignore. The other is not optional, and always has its effect. The "hint" is that the compiler is advised to replace calls to that function with a copy of the code for the function itself.
The guaranteed effect is that an inline function can be defined in multiple translation units, and those be linked together, without a multiple definition error, and all but one of the copies is removed by the linker. So, if the example above appears in a header file which is shared between multiple translation units, bar needs to be explicitly marked inline. Otherwise, the linker will discover multiple definitions of bar, which is not allowed.
Despite the name, inline in C++ is mostly about the second, compulsory effect, not the first, optional one. Modern optimising compilers have their own ideas about which calls should be inlined, and don't pay a whole lot of attention to inline when making that decision. For instance I've seen it have an effect in gcc at moderate optimisation levels, but at low levels approximately nothing is inlined, and at high levels approximately everything is (if the definition is available when the call is compiled) unless it makes the function too big.
Whether a function is defined in a header or in a cpp file has absolutely no effect on anything by itself. You can safely imagine that what #include does is copy and paste the header file into the cpp file in the preprocessor, before the compiler ever sees it. If a function is defined in the same translation unit as a call to it, then the function code is available to be inlined by the compiler. If they're in different translation units, then the code is not available and the call can only be inlined by the linker, with whole-program optimisation or similar. A "translation unit" more or less means, "a cpp file, after all the headers have been copy and pasted into it".
C++ compilers are free to choose what will be inline and what won't, no matter what hints you give them. It shouldn't matter if the function is part of a class or not, or whether it is in a header file or source file; the compiler doesn't pay attention to those things while making its decision.
No, not always. The compiler treats it as a hint, just like the inline keyword, but it mostly decides on its own, because it knows better than you what the costs and benefits may be. Inlining the code avoids the function call overhead, but makes the code bigger, which has negative performance impacts on the instruction cache.
These performance hints from the programmer are generally more and more often ignored by the compiler. What it does not ignore (or rather, what the linker does not ignore) is that a function declared inline may appear in several compilation units, and should be treated as multiple copies of the same function without resulting in linker errors.
If you place the definition of a free non-template function in a header file, you will end up with a function definition in each .cpp file that includes the header (directly or indirectly). This can lead to problems when linking.
However, if you declare the function to be inline, the linker will make sure you only use a single definition even if it is included at multiple places.
I have a class which has many small functions. By small functions, I mean functions that doesn't do any processing but just return a literal value. Something like:
string Foo::method() const{
return "A";
}
I have created a header file "Foo.h" and source file "Foo.cpp". But since the function is very small, I am thinking about putting it in the header file itself. I have the following questions:
Is there any performance or other issues if I put these function definition in header file? I will have many functions like this.
My understanding is when the compilation is done, compiler will expand the header file and place it where it is included. Is that correct?
If the function is small (the chance you would change it often is low), and if the function can be put into the header without including myriads of other headers (because your function depends on them), it is perfectly valid to do so. If you declare them extern inline, then the compiler is required to give it the same address for every compilation unit:
headera.h:
inline string method() {
return something;
}
Member functions are implicit inline provided they are defined inside their class. The same stuff is true for them true: If they can be put into the header without hassle, you can indeed do so.
Because the code of the function is put into the header and visible, the compiler is able to inline calls to them, that is, putting code of the function directly at the call site (not so much because you put inline before it, but more because the compiler decides that way, though. Putting inline only is a hint to the compiler regarding that). That can result in a performance improvement, because the compiler now sees where arguments match variables local to the function, and where argument doesn't alias each other - and last but not least, function frame allocation isn't needed anymore.
My understanding is when the compilation is done, compiler will expand the header file and place it where it is included. Is that correct?
Yes, that is correct. The function will be defined in every place where you include its header. The compiler will care about putting only one instance of it into the resulting program, by eliminating the others.
Depending on your compiler and it's settings it may do any of the following:
It may ignore the inline keyword (it
is just a hint to the compiler, not a
command) and generate stand-alone
functions. It may do this if your
functions exceed a compiler-dependent
complexity threshold. e.g. too many
nested loops.
It may decide than your stand-alone
function is a good candidate for
inline expansion.
In many cases, the compiler is in a much better position to determine if a function should be inlined than you are, so there is no point in second-guessing it. I like to use implicit inlining when a class has many small functions only because it's convenient to have the implementation right there in the class. This doesn't work so well for larger functions.
The other thing to keep in mind is that if you are exporting a class in a DLL/shared library (not a good idea IMHO, but people do it anyway) you need to be really careful with inline functions. If the compiler that built the DLL decides a function should be inlined you have a couple of potential problems:
The compiler building the program
using the DLL might decide to not
inline the function so it will
generate a symbol reference to a
function that doesn't exist and the
DLL will not load.
If you update the DLL and change the
inlined function, the client program
will still be using the old version
of that function since the function
got inlined into the client code.
There will be an increase in performance because implementation in header files are implicitly inlined. As you mentioned your functions are small, inline operation will be so beneficial for you IMHO.
What you say about compiler is also true.There is no difference for compiler—other than inlining—between code in header file or .cpp file.
If your functions are that simple, make them inline, and you'll have to stick them in the header file anyway. Other than that, any conventions are just that - conventions.
Yes, the compiler does expand the header file where it encounters the #include statements.
It depends on the coding standards that apply in your case but:
Small functions without loops and anything else should be inlined for better performance (but slightly larger code - important for some constrained or embedded applications).
If you have the body of the function in the header you will have it by default inline(d) (which is a good thing when it comes to speed).
Before the object file is created by the compiler the preprocessor is called (-E option for gcc) and the result is sent to the compiler which creates the object out of code.
So the shorter answer is:
-- Declaring functions in header is good for speed (but not for space) --
C++ won’t complain if you do, but generally speaking, you shouldn’t.
when you #include a file, the entire content of the included file is inserted at the point of inclusion. This means that any definitions you put in your header get copied into every file that includes that header.
For small projects, this isn’t likely to be much of an issue. But for larger projects, this can make things take much longer to compile (as the same code gets recompiled each time it is encountered) and could significantly bloat the size of your executable. If you make a change to a definition in a code file, only that .cpp file needs to be recompiled. If you make a change to a definition in a header file, every code file that includes the header needs to be recompiled. One small change can cause you to have to recompile your entire project!
Sometimes exceptions are made for trivial functions that are unlikely to change (e.g. where the function definition is one line).
Source: http://archive.li/ACYlo (previous version of Chapter 1.9 on learncpp.com)