Code files (with a .cpp extension) are not the only files commonly seen in programs. The other type of file is called a header file, sometimes known as an include file. Header files almost always have a .h extension. The purpose of a header file is to hold declarations for other files to use.
Using standard library header files
Consider the following program:
#include <iostream>
int main()
{
using namespace std;
cout << "Hello, world!" << endl;
return 0;
}
This program prints “Hello, world!” to the console using cout. However, our program never defines cout, so how does the compiler know what cout is? The answer is that cout has been declared in a header file called “iostream”. When we use the line #include , we are telling the compiler to locate and then read all the declarations from a header file named “iostream”.
Keep in mind that header files typically only contain declarations. They do not define how something is implemented, and you already know that your program won’t link if it can’t find the implementation of something you use. So if cout is only defined in the “iostream” header file, where is it actually implemented? It is implemented in the runtime support library, which is automatically linked into your program during the link phase.

A library is a package of code that is meant to be reused in many programs. Typically, a library includes a header file that contains declarations for everything the library wishes to expose (make public) to users, and a precompiled object that contains all of the implementation code compiled into machine language. These libraries typically have a .lib or .dll extension on Windows, and a .a or .so extension on Unix. Why are libraries precompiled? First, since libraries rarely change, they do not need to be recompiled often, if ever. It would be a waste of time to compile them every time you wrote a program that used them. Second, because precompiled objects are in machine language, it prevents people from accessing or changing the source code, which is important to businesses or people who don’t want to make their source code available for intellectual property reasons.
Writing your own header files
Now let’s go back to the example we were discussing in the previous lesson. When we left off, we had two files, add.cpp and main.cpp, that looked like this:
add.cpp:
int add(int x, int y)
{
return x + y;
}
main.cpp:
#include <iostream>
int add(int x, int y); // forward declaration using function prototype
int main()
{
using namespace std;
cout << "The sum of 3 and 4 is " << add(3, 4) << endl;
return 0;
}
We’d used a forward declaration so that the compiler would know what add was when compiling main.cpp. As previously mentioned, writing forward declarations for every function you want to use that lives in another files can get tedious quickly.
Header files can relieve us of this burden. A header file only has to be written once, and it can be included in as many files as needed. This also helps with maintenance by minimizing the number of changes that need to be made if a function prototype ever changes (eg. by adding a new parameter).
Writing our own header files is surprisingly easy. Header files consist of two parts. The first part is called a header guard, which is discussed in the next lesson (on the preprocessor). The second part is the actual content of the .h file, which should be the declarations for all of the functions we want other files to be able to see. Our header files should all have a .h extension, so we’ll call our new header file add.h:
add.h:
#ifndef ADD_H #define ADD_H int add(int x, int y); // function prototype for add.h #endif
In order to use this header file in main.cpp, we have to include it. Here is the new main.cpp:
main.cpp that includes add.h:
#include <iostream>
#include "add.h" // this brings in the declaration for add()
int main()
{
using namespace std;
cout << "The sum of 3 and 4 is " << add(3, 4) << endl;
return 0;
}
When the compiler compiles the #include "add.h" line, it copies the contents of add.h into the current file. Because our add.h contains a function prototype for add(), this prototype is now being used as a forward declaration of add()!
Consequently, our program will compile and link correctly.

You’re probably curious why we use angled brackets for iostream, and double quotes for add.h. The answer is that angled brackets are used to tell the compiler that we are including a header file that was included with the compiler. The double-quotes tell the compiler that this is a header file we are supplying, which causes it to look for that header file in the current directory containing our source code first.
Rule: Use angled brackets to include header files that come with the compiler. Use double quotes to include any other header files.
Another commonly asked question is “why doesn’t iostream have a .h extension?”. The answer is, because iostream.h is a different header file than iostream is! To explain requires a very short history lesson.
When C++ was first created, all of the files in the standard runtime library ended in .h. Life was consistent, and it was good. The original version of cout and cin lived in iostream.h. When the language was standardized by the ANSI committee, they decided to move all of the functions in the runtime library into the std namespace (which is generally a good idea). However, this presented a problem: if they moved all the functions into the std namespace, none of the old programs would work any more!
To try to get around this issue and provide backwards compatibility for older programs, a new set of header files was introduced that use the same names but lack the .h extension. These new header files have all their functionality inside the std namespace. This way, older programs that include #include do not need to be rewritten, and newer programs can #include .
Make sure when you include a header file from the standard library that you use the non .h version if it exists. Otherwise you will be using a deprecated version of the header that is no longer supported.
As a side note, many headers in the standard library do not have a non .h version, only a .h version. For these files, it is fine to include the .h version. Many of these libraries are backwards compatible with standard C programming, and C does not support namespaces. Consequently, the functionality of these libraries will not be accessed through the std namespace. Also, when you write your own header files, they will all have a .h extension, since you will not be putting your code in the std namespace.
Rule: use the non .h version of a library if it exists, and access the functionality through the std namespace. If the non .h version does not exist, or you are creating your own headers, use the .h version
1.10 — A first look at the preprocessor
|
Index
|
1.8 — Programs with multiple files
|
1.10 — A first look at the preprocessor
Index
1.8 — Programs with multiple files
Ok I have an issue here with the headers. I deviated from the last lesson slighy but it is close to the same. Please tell me where I went wrong with Header Files.
Here is Program1.cpp
// Program1.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include "MATH.h" int main() { using namespace std; int a = 0; int b = 0; cout > a; cout > b; cout And here is MATH.cpp#ifndef MATH_H #define MATH_H int Multiply(int x, int y) { using namespace std; return x * y; } int Add(int x, int y) { using namespace std; return x + y; } int Subtract(int x, int y) { using namespace std; return x - y; } #endifHere is my output from VS2008:
1>—— Build started: Project: Program1, Configuration: Debug Win32 ——
1>Compiling…
1>Program1.cpp
1>c:\documents and settings\jstuart\my documents\visual studio 2008\projects\program1\program1\program1.cpp(18) : error C3861: ‘Multiply’: identifier not found
1>c:\documents and settings\jstuart\my documents\visual studio 2008\projects\program1\program1\program1.cpp(19) : error C3861: ‘Add’: identifier not found
1>c:\documents and settings\jstuart\my documents\visual studio 2008\projects\program1\program1\program1.cpp(20) : error C3861: ‘Subtract’: identifier not found
1>MATH.cpp
1>c:\documents and settings\jstuart\my documents\visual studio 2008\projects\program1\program1\math.cpp(28) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add ‘#include “stdafx.h”‘ to your source?
1>Generating Code…
1>Build log was saved at “file://c:\Documents and Settings\jstuart\My Documents\Visual Studio 2008\Projects\Program1\Program1\Debug\BuildLog.htm”
1>Program1 - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The problem might be that you named your math.h file math.cpp. Try renaming your math.cpp to math.h and see if it fixes your issue. If that doesn’t work, try reposting your problem in the forum. The forums don’t have any many problems with posted programs as wordpress seems to.
Spot on that worked. I changed MATH.cpp to Math.h and it worked fine. Thanks for the tutorial and the response Alex.
Hmm, first of all great job with the tutorials. I have finally decided to familiarize myself with C++ and I really like it so far, however I’m a bit confused with this and have a question.
So my question is the following: Should be include the header file for every source file (in this case I’m thinking about add.cpp or can we only use it for one source file. Also, isn’t it going to scream at us for “redefining?” the functions?
Edit: I just found out. The header guard prevent that from happenning. As for using it in all the source files makes it easier and saves times?
Excuse my english, it is not my native tongue. :P
As you’ve noted, the header guards prevent the header files from being included multiple times. It’s a sloppy way of doing things, in my opinion, but it works and it’s the standard way to do it.
Ideally, you should include your header file in every .cpp file in which you use the stuff it declares. However, in practice, since header files can include other header files, this may not be strictly necessary. For example, you might have a class named Foo that uses strings, so foo.h will include string.h. foo.cpp (which also uses strings) should ideally include both foo.h and string.h, but since foo.h already includes string.h, if you only include foo.h you will still be able to use strings.
I use Bloodshed Dev-C++ and i keep geting these error messages while trying to compile:
C:Dev-CppMakefile.win [Build Error] [Project1.exe] Error 1
ld returned 1 exit status
[Linker error] undefined reference to `add(int, int)’
I copied the add header and saved it as a .h file in the same directory as the project. Has anyone else had this error? How can I fix it?
Nevermind, I got it to work by changing the header from:
add(int x, int y)
to:
add(int x, int y)
{ return x + y: }
I had this problem too and couldn’t understand what was being wrong (I was trying out the IDE Geany).
Until I realised that Geany didn’t compile both of the two .cpp files, and link them together.
When I manually compiled/linked them with g++ it worked just fine.
Another interesting part of the tutorial. I learnt a lot about namespaces here. Thanks again for the great tutorial
I’m guessing
This way, older programs that include #include do not need to be rewritten, and newer programs can #include
should read
This way, older programs that include #include iostream.c do not need to be rewritten, and newer programs can #include <iostream>