I somehow can't grab the idea and reading the documentation hasn't helped me.
My questions are:
When I include a header file #include "general.h", and in the directory of my project there are two files general.h and general.cpp, does it mean that I the precompiler will find the .cpp file automatically?
Can I include files without extentions: #include "general"?
Can I include a file without any header file: #include "general.cpp"?
Can I include a txt file: #include "general.txt"?
I tried this all in Visual Studio 2010. No syntax errors at least. But I'd like to have an explanation. So, I hope you will be kind and help me.
The standard and the compiler don't really care much about whether a file is .cpp or .h or .monkeyface. The concepts behind structuring your source code into implementation and header files are really just accepted ways to help manage your source. Despite this, not structuring your source in the accepted way is often considered to be incorrect or bad C++.
All #include does is tell the preprocessor to include the contents of the file you specify in the current file. It's like copying and pasting the other file into yours. When you say #include "foo.h", it just includes the contents of foo.h and doesn't care about foo.cpp at all - it doesn't even know that it exists (and there's no reason it has to exist).
Structuring your source code in implementation and header files is extremely useful - it avoids problems with dependencies and multiple definitions, and also improves compilation time somewhat. When your code uses another class, you only need to #include the header file for that class. The reason is because your code doesn't need to care about the implementation of the class, it just needs to know what it looks like (its name, members, base class, etc.). It doesn't concern itself with how exactly the member functions are implemented.
The extensions .cpp and .h are merely conventions. Some people prefer to use .hpp for header files. Some people even use .tpp for template implementations. You can name them however you like - yes, you can even include a .txt file. Your compiler probably tries to infer things about files (for example, which language to compile it as) from the file extension, but that is usually overrideable.
So if your main.cpp includes foo.h because it uses class foo, at what point does foo.cpp get involved? Well, in the compilation of main.cpp, it doesn't get involved at all. main.cpp doesn't need to know about the implementation of the class, as we discussed above. However, when compiling your entire program, you will pass each of your .cpp files to the compiler to be compiled separately. That is, you would do something like g++ main.cpp foo.cpp. When foo.cpp is compiled, it will include the headers that it needs to compile.
After each of your .cpp files has been compiled (which involves including the headers that they depend on), they are then linked together. The use of a member function foo::bar() in main.cpp will at this stage be linked to the implementation of foo::bar() that was given in foo.cpp.
The #include directive tells the preprocessor to read the file. That's all.
The preprocessor simply inserts the whole content of the given file when it encounters a #include directive.
No, the precompiler know nothing about the .cpp file
Yes, if the file has no extensions
You can include any file you want. It doesn't mean you will get anything useful out of it.
See point 3. above.
#include is a simple "insert the contents of the given file here" mechanism, so the preprocessor will include exactly the file you specify. If you include a .h file, neither the preprocessor nor the compiler will know about the corresponding .cpp file - each .cpp file is compiled separately (the purpose of the .h files is to inform the compiler of which functions exist outside of the current .cpp file). After compilation, the linker is invoked, and only then are the compiled results of the different .cpp files combined.
Related
I am having trouble understanding an answer I saw in another post. It said that it is good practice to define a struct in a separate .h file so it can be used in other files. I think that is great and it solves my current dilemma, however I have a question about compilation and makefiles. I am only familiar with having header files that are associated with .cpp files at the moment.
Can someone explain how that implementation would look when I have a .h and no .cpp? Do I need an implementation file as well? Also, how do I link the header in a makefile? Currently I only know how to compile a .cpp & header into a .o file and link them.
Thanks, and sorry for taking us back to c++ kindergarten. This is a new revelation and seems like a good one.
You don't need a matching source file (.c or .cpp) for every header .h file.
Having header files without corresponding source files is just fine.
When you #include some header file, you can think of it as a kind of "copy and paste" operation: the preprocessor copies the content of the header file, and pastes it in the point of inclusion.
(Well, there are some details to consider here, for example the presence of a #pragma once directive or some #ifdef inclusion guard can prevent multiple inclusions of the same header file in a given project.)
The C and C++ compilers will then process the whole "compilation unit", i.e. the current source file with all the included headers.
The key concept is that you define the struct/class in a .h header, so that you can use it in multiple .cpp files. Whenever you need struct foo defined in foo.h, you #include "foo.h". You don't need to directly compile the header file, it will be pulled in by whichever source file uses it. Therefore you don't need a make target for .h in normal circumstances.
If the definition in the header is never used, it won't be pulled in and that's it.
I have "Hello World" code that uses function fhi from another hi.cpp file that has it's header.
Correct my if my understanding is wrong according following:
I can do include cpp file like #include "c:\c\hi.cpp" instead of using header without any problems except that fact that it looks more readable in header file.
If I include header like sample in my main program hi.h, must hi.h include hi.cpp, or it is done automatically according the same file name hi. I'm wondering how compiler knows where is function fhi body.
Is it possible to have different names for header and cpp files?
Programm:
#include "stdafx.h"
#include "c:\c\hi.h"
int _tmain(int argc, _TCHAR* argv[])
{
fhi(1);
return 0;
}
hi.h
#include <cstdlib>
#include <iostream>
int var;
int fhi(int f);
hi.cpp
#include <cstdlib>
#include <iostream>
int fhi(int f)
{
return 0;
}
must hi.h include hi.cpp
No. hi.h contains only declarations, that can be other by other .cpp files.
I'm wondering how compiler knows where is function fhi body.
It doesn't. You need to compile all *.cpp files into the object files. In your case, you will have two object files: program.o and hi.o. The linker can now take these two object files, and spit out the executable. References to other functions(in this case the actual definition of fhi(..)) is resolved in this stage.
Also why are you using absolute paths in #includes? It will break when you move the "c" directory around.
What normally happens is that the build system compiles the .cpp files into object files, that then are used to build the main executable. The means to tell this to the build system vary greatly.
One important point is that your hi.cpp must include hi.h. You should also put an include guard in hi.h, to make it safe to be included more than once in a translation unit.
I can do include cpp file like #include "c:\c\hi.cpp" instead of using
header without any problems except that fact that it looks more
readable in header file.
yes, you can do so but it is not recommended, one of the problems is encapsulation; you are not hiding implementation details. readability as you mention is also a concern, a header is easier to read since it clearly shows what methods are public.
If I include header like sample in my main program hi.h, must hi.h
include hi.cpp, or it is done automatically according the same file
name hi. I'm wondering how compiler knows where is function fhi body.
the header needs to be explicitly included in hi.cpp and any .cpp file that use the class defined in the header.
Is it possible to have different names for header and cpp files?
yes but it is not recommended, it makes it more difficult to find things.
as a general rule: think about that other programmers may want to look in your code so you need to structure it so that it is easy to read and understand as well as making it easier for you 2 years down the road to remember where things are.
In Visual Studio all CPP files included in the project will be compiled to produce OBJ files. These OBJ files will be linked together to form the EXE or DLL.
Including files are similar to pasting the contents of the file at that location. The only difference is that this pasting is done by the pre-compiler during compilation.
Finding out where a function body resides is done by the either the compiler if the function is inline or by the linker when the final binary is created.
First, if the header file is in the same directory as the source file including it, you can use just
#include "hi.h"
In other words, you don't have to use a full path. (See e.g. the inclusion of "stdafx.h".)
Second, in your header file you don't need to include other header files, unless you need types from those. In your header file you don't have anything that needed from the header files you include.
Third, you should protect header files header files from being included more than once in the same source file, this can be done with a so called include guard, on in some compiler via a special directive called #pragma once.
Fourth, in your header file you define a global variable var. This variable will then be defined in every source file you include the header file in, which will lead to errors. You need to declare the variable as extern:
extern int var;
Then in one source file you define the variable like you do now.
Fifth, you should never include source files in header file (with some special exceptions that you don't have to think about yet). Instead you add all source files to the project (I assume you are in MS VisualStudio) and it they will all be built and linked together automatically.
Sixth, since you seem to be using VisualC++, then you are probably using something called precompiled headers. This is something the compiler uses to speed up compilation. However, for this to work you have to include "stdafx.h" in all source files. That include actually has to be the first non-comment line in each source file.
We define a C++ class in a .h and define its methods in a .cpp, but it makes the code look less organized.
I want to put all method's definition in the class definition which is in a .h file, but I'm worrying that the compiler generate duplicated code for the same methods/functions when one class header file is included by different files.
Does the linker find out and merge the duplicated code pieces to reduce the file size?
If not, is it better to use .hpp instead? I heard that a .hpp is for this.
And it does make minor difference when I just change a .h file for a .hpp (I don't know why), compiled with G++.
Yes. It may create larger executable and that is because the member functions which are defined in the class itself, are inline by default, whether you mention the keyword inline in the defintion or not. Usually, inline function causes larger executable because the compiler will define it multiple times wherever it is called from.
.h vs .hpp is the 90% equivalence of
#include <cmath> vs #include <math.h>
Some people prefer to use .hpp when they are doing exclusive C++ programming. You will see .hpp in libraries like Boost.
However, the other 10% is really important. For example, taking from Boost library doc, they explain the reason of using .hpp over .h:
Most Boost libraries are header-only: they consist entirely of header
files containing templates and inline functions, and require no
separately-compiled library binaries or special treatment when
linking.
If you fall in that case, you should use .hpp, but this can cost longer compilation time. Otherwise, you might want to keep .h style. That's just my personal taste. It isn't C-oriented at all, in my honest opinion.
Further reading:
Splitting templated C++ classes into .hpp/.cpp files--is it possible?
Condensing Declaration and Implementation into an HPP file
C++ templates declare in .h, define in .hpp
You have nothing to worry about. It makes absolutely no difference how it's broken up, it's what your files describe that makes it bigger, not how that description is spread out.
.h or .hpp makes no difference as well.
To answer your question about a larger executable, yes it will make your executable larger. When a you #include a header file in a source or header file, the preprocessor replaces the #include with the contents of the header file. This is why it is necessary to protect your header files with the following header protection:
#ifndef HDR_H
#define HDR_H
...
#endif
However, you will get linker errors if you include the header file (that has function definitions) in multiple files that are part of the same executable. It would wise for you to split class and function definitions and declarations into .cpp and .hpp files, respectively. This will greatly reduce the amount of linker headaches.
Also, .h = .hpp. Doesn't matter which one you choose. Personal preference...
There's all you need here: Header files, pros and cons of putting all you code in them. Hope it helps!
Using header files results in quicker compile time and smaller executable. It also looks considerably cleaner because you can get a quick overview of your class by looking at its .h declaration.
In Python whenever I had a bunch of functions that I wanted to use across multiple programs I'd make another .py file and then just import that wherever I needed it. How would I do that in C/C++? Do I dump both prototype and implementation into an .h file? or do I need to place the function prototypes in the .h file and the implementations in a separate .cpp file with the same name as the .h file and #include the .h wherever I need it?
You need to do a couple of things:
Add the prototype to a header file.
Write a new source file with the function definitions.
In a source file that just wants to use the shared function, you need to add #include "header.h" (replacing header.h with the name of the file from step 1) someplace before you try to call the shared function (normally you put all includes at the top of the source file).
Make sure your build compiles the new source file and includes that in the link.
A couple of other comments. It's normal to have foo.h as the header for the foo.c but that is only a style guideline.
When using headers, you want to add include guards to protect against the multiple include issue.
In C/C++ we usually put declarations in .h files and implementation in .c/cpp files.
(Note: there're many other ways, for example the include, templates, inline, extern, ... so you may find some code only in header files or only in c/cpp files - for example some of the STL and templates.)
Then you need to "link" the file with your program, which works like the "import" in Python interpreter but actually works in static linking object files together into a single executable file.
However the "link" command and syntax depends on your compiler and OS linker. So you need to check your compiler for more information, for example "ld" on UNIX and "link.exe" on DOS/Windows. Moreover, usually the C compiler will invoke the linker automatically.
For example, say you have 2 files: a.c and b.c (with a.h and b.h), on gcc:
gcc -o a.out a.c b.c
On MSVC:
cl a.c b.c
There are two ways to approach this that differ only slightly. As others have said, the first steps are:
-Create a header file which contains your function prototypes. You'll want to mark this with
# ifndef myheader_h
# define myheader_h
// prototypes go here...
# endif
to prevent problems with multiple inclusions.
-Create a .c file which contains the actual definitions.
Here's where the solutions branch.
If you want to include the source directly in your project, make the .c file part of your compilation stage as well as your link stage.
However, if you really plan on using this across multiple projects, you'll probably want to compile this source file independently, and reference the object file from your other projects. This is loosely what a "library" is, though libraries may consist of multiple object modules - each of which has been compiled but not yet linked.
update
Someone pointed out that this really only keeps the header from being included in a single cpp file. News flash: that's all you need to do.
Compilers treat each cpp file individually. The header files included by each cpp source file tell the compiler, "hey! This thing is defined in another source file! Assume references that match this prototype are A-OK and keep moving on."
The LINKER, on other other hand, is responsible for fixing up these references, and IT will throw a fit if the same symbol is defined in multiple object files. For that to happen, a function would have to be defined in two separate source files - a real definition with a body, not just an extern prototype - OR the object file that contains its body/definition would have to be included in the link command more than once.
Re:"inline"
Use of "inline" is meant as an optmization feature. Functions declared as inline have their bodies expanded inline at each place where they are called. Using this to get around multiple definition errors is very, very bad. This is similar to macro expansion.
See Francis's answer. The sentence that you wrote, "or do I need to place the function prototypes in the .h file and the implementations in a separate .cpp file with the same name as the .h file and #include the .h wherever I need it?", is pretty-much correct. You don't have to do things exactly this way, but it works.
It's up to you how you do this, The compiler doesn't care. But if you put your functions in a .h file, you should declare them __inline otherwise if you include the header file in more than one .cpp file, you will have multiply defined symbols.
On the other hand, if you make them __inline, you will tend to get a copy created in each place that you use the function. This will bloat the size of your program. So unless the functions are quite small, it's probably best to put the functions in a .cpp and create a parallel .h with function prototypes and public structures. This is the way most programmers work.
On the other hand, in the STL (Standard Template Library), virtually all of the code is in header files. (without the .h extension)
I was just wondering what the difference between .cpp and .h files is? What would I use a header file (.h) for and what would I use a cpp file for?
In general, and it really could be a lot less general:
.h (header) files are for declarations of things that are used many times, and are #included in other files
.cpp (implementation) files are for everything else, and are almost never #included
Technically, there is no difference. C++ allows you to put your code in any file, with any format, and it should work.
By convention, you put your declarations (basically, that which makes up your API) in the .h files, and are referred to as "headers". The .cpp files are for the actual "guts" of your code - the implementation details.
Normally, you have the header files included with #include by other files in your project (and other projects, if you're making a library), so the compiler can get the interface required to compile. The implementation, in the .cpp files, is typically implemented so there is one .cpp file "filling in" the implementation per .h file.
By convention, .h files is something that you #include. CPP files are something you add to your project for compiling into separate object file, and then passing to the linker.
The .h file is called the header file. You usually put your interface there (the stuff you want to be public). The cpp file is where you actually implement your interface.
First, both are text files that contain code for the C++ compiler or pre-processor. As far as the system is concerned there is no difference.
By convention different file name extensions are used to indicate the content of files. In C programs you tend to see .h and .c files while in C++ .hpp and .cpp serve the same purposes.
The first group, .h and .hpp files, called header files, contains mostly non-executing code such as definitions of constants and function prototypes. They are added to programs via #include directive and used not only by the program or library in question but by other programs or libraries that will make use of them, declaring interface points and contracts defining values. They are also used to set metadata that may change when compiling for different operating systems.
The second group, .c and .cpp files, contain the executing parts of the code for the library or program.
Correct me if I'm wrong but,
When you #include something, it more-or-less inserts the entire included file into the one with the include command; that is, when I include, say "macros.h" in "genericTools.cpp", the entire contents of "macros.h" is placed in "genericTools.cpp" at that point. This is why you need to use things like "#pragma once" or other protections, to prevent including the same file twice.
Of note, templated code needs to be entirely in the file you're going to be including elsewhere. (I'm unsure of this - can template specializations be ommited from the included files, and linked like a normal function?)
The .cpp that is the implementation file is our actual program or code.
When we need to use different inbuilt functions in our code, we must include the header file that is .h files.
These .h files contains the actual code of the inbuilt functions that we use hence we can simply call the respective functions.
Therefore, while we compile our code we can see more number of lines compiled than what we have actually coded because not only our code is compiled but along with that the (code of the) functions (that are included in .h files) are also compiled.