The duplicate definition problem
In lesson 2.6 -- Forward declarations and definitions, we noted that a variable or function identifier can only have one definition (the one definition rule). Thus, a program that defines a variable identifier more than once will cause a compile error:
1 2 3 4 5 6 7 |
int main() { int x; // this is a definition for variable x int x; // compile error: duplicate definition return 0; } |
Similarly, programs that define a function more than once will also cause a compile error:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> int foo() // this is a definition for function foo { return 5; } int foo() // compile error: duplicate definition { return 5; } int main() { std::cout << foo(); return 0; } |
While these programs are easy to fix (remove the duplicate definition), with header files, it’s quite easy to end up in a situation where a definition in a header file gets included more than once. This can happen when a header file #includes another header file (which is common).
Consider the following academic example:
square.h:
1 2 3 4 5 6 |
// We shouldn't be including function definitions in header files // But for the sake of this example, we will int getSquareSides() { return 4; } |
geometry.h:
1 |
#include "square.h" |
main.cpp:
1 2 3 4 5 6 7 |
#include "square.h" #include "geometry.h" int main() { return 0; } |
This seemingly innocent looking program won’t compile! Here’s what’s happening. First, main.cpp #includes square.h, which copies the definition for function getSquareSides into main.cpp. Then main.cpp #includes geometry.h, which #includes square.h itself. This copies contents of square.h (including the definition for function getSquareSides) into geometry.h, which then gets copied into main.cpp.
Thus, after resolving all of the #includes, main.cpp ends up looking like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int getSquareSides() // from square.h { return 4; } int getSquareSides() // from geometry.h (via square.h) { return 4; } int main() { return 0; } |
Duplicate definitions and a compile error. Each file, individually, is fine. However, because main.cpp ends up #including the content of square.h twice, we’ve run into problems. If geometry.h needs getSquareSides(), and main.cpp needs both geometry.h and square.h, how would you resolve this issue?
Header guards
The good news is that we can avoid the above problem via a mechanism called a header guard (also called an include guard). Header guards are conditional compilation directives that take the following form:
1 2 3 4 5 6 |
#ifndef SOME_UNIQUE_NAME_HERE #define SOME_UNIQUE_NAME_HERE // your declarations (and certain types of definitions) here #endif |
When this header is #included, the preprocessor checks whether SOME_UNIQUE_NAME_HERE has been previously defined. If this is the first time we’re including the header, SOME_UNIQUE_NAME_HERE will not have been defined. Consequently, it #defines SOME_UNIQUE_NAME_HERE and includes the contents of the file. If the header is included again into the same file, SOME_UNIQUE_NAME_HERE will already have been defined from the first time the contents of the header were included, and the contents of the header will be ignored (thanks to the #ifndef).
All of your header files should have header guards on them. SOME_UNIQUE_NAME_HERE can be any name you want, but by convention is set to the full filename of the header file, typed in all caps, using underscores for spaces or punctuation. For example, square.h would have the header guard:
square.h:
1 2 3 4 5 6 7 8 9 |
#ifndef SQUARE_H #define SQUARE_H int getSquareSides() { return 4; } #endif |
Even the standard library headers use header guards. If you were to take a look at the iostream header file from Visual Studio, you would see:
1 2 3 4 5 6 |
#ifndef _IOSTREAM_ #define _IOSTREAM_ // content here #endif |
For advanced readers
In large programs, it’s possible to have two separate header files (included from different directories) that end up having the same filename (e.g. directoryA\config.h and directoryB\config.h). If only the filename is used for the include guard (e.g. CONFIG_H), these two files may end up using the same guard name. If that happens, any file that includes (directly or indirectly) both config.h files will not receive the contents of the include file to be included second. This will probably cause a compilation error.Because of this possibility for guard name conflicts, many developers recommend using a more complex/unique name in your header guards. Some good suggestions are a naming convention of <PROJECT>_<PATH>_<FILE>_H , <FILE>_<LARGE RANDOM NUMBER>_H, or <FILE>_<CREATION DATE>_H
Updating our previous example with header guards
Let’s return to the square.h example, using the square.h with header guards. For good form, we’ll also add header guards to geometry.h.
square.h
1 2 3 4 5 6 7 8 9 |
#ifndef SQUARE_H #define SQUARE_H int getSquareSides() { return 4; } #endif |
geometry.h:
1 2 3 4 5 6 |
#ifndef GEOMETRY_H #define GEOMETRY_H #include "square.h" #endif |
main.cpp:
1 2 3 4 5 6 7 |
#include "square.h" #include "geometry.h" int main() { return 0; } |
After the preprocessor resolves all of the includes, this program looks like this:
main.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#ifndef SQUARE_H // square.h included from main.cpp, #define SQUARE_H // SQUARE_H gets defined here // and all this content gets included int getSquareSides() { return 4; } #endif // SQUARE_H #ifndef GEOMETRY_H // geometry.h included from main.cpp #define GEOMETRY_H #ifndef SQUARE_H // square.h included from geometry.h, SQUARE_H is already defined from above #define SQUARE_H // so none of this content gets included int getSquareSides() { return 4; } #endif // SQUARE_H #endif // GEOMETRY_H int main() { return 0; } |
As you can see from the example, the second inclusion of the contents of square.h (from geometry.h) gets ignored because SQUARE_H was already defined from the first inclusion. Therefore, function getSquareSides only gets included once.
Header guards do not prevent a header from being included once into different code files
Note that the goal of header guards is to prevent a code file from receiving more than one copy of a guarded header. By design, header guards do not prevent a given header file from being included (once) into separate code files. This can also cause unexpected problems. Consider:
square.h:
1 2 3 4 5 6 7 8 9 10 11 |
#ifndef SQUARE_H #define SQUARE_H int getSquareSides() { return 4; } int getSquarePerimeter(int sideLength); // forward declaration for getSquarePerimeter #endif |
square.cpp:
1 2 3 4 5 6 |
#include "square.h" // square.h is included once here int getSquarePerimeter(int sideLength) { return sideLength * getSquareSides(); } |
main.cpp:
1 2 3 4 5 6 7 8 9 10 |
#include "square.h" // square.h is also included once here #include <iostream> int main() { std::cout << "a square has " << getSquareSides() << " sides\n"; std::cout << "a square of length 5 has perimeter length " << getSquarePerimeter(5) << '\n'; return 0; } |
Note that square.h is included from both main.cpp and square.cpp. This means the contents of square.h will be included once into square.cpp and once into main.cpp.
Let’s examine why this happens in more detail. When square.h is included from square.cpp, SQUARE_H is defined until the end of square.cpp. This define prevents square.h from being included into square.cpp a second time (which is the point of header guards). However, once square.cpp is finished, SQUARE_H is no longer considered defined. This means that when the preprocessor runs on main.cpp, SQUARE_H is not initially defined in main.cpp.
The end result is that both square.cpp and main.cpp get a copy of the definition of getSquareSides. This program will compile, but the linker will complain about your program having multiple definitions for identifier getSquareSides!
The best way to work around this issue is simply to put the function definition in one of the .cpp files so that the header just contains a forward declaration:
square.h:
1 2 3 4 5 6 7 |
#ifndef SQUARE_H #define SQUARE_H int getSquareSides(); // forward declaration for getSquareSides int getSquarePerimeter(int sideLength); // forward declaration for getSquarePerimeter #endif |
square.cpp:
1 2 3 4 5 6 7 8 9 10 11 |
#include "square.h" int getSquareSides() // actual definition for getSquareSides { return 4; } int getSquarePerimeter(int sideLength) { return sideLength * getSquareSides(); } |
main.cpp:
1 2 3 4 5 6 7 8 9 10 |
#include "square.h" // square.h is also included once here #include <iostream> int main() { std::cout << "a square has " << getSquareSides() << "sides\n"; std::cout << "a square of length 5 has perimeter length " << getSquarePerimeter(5) << '\n'; return 0; } |
Now when the program is compiled, function getSquareSides will have just one definition (via square.cpp), so the linker is happy. File main.cpp is able to call this function (even though it lives in square.cpp) because it includes square.h, which has a forward declaration for the function (the linker will connect the call to getSquareSides from main.cpp to the definition of getSquareSides in square.cpp).
Can’t we just avoid definitions in header files?
We’ve generally told you not to include function definitions in your headers. So you may be wondering why you should include header guards if they protect you from something you shouldn’t do.
There are quite a few cases we’ll show you in the future where it’s necessary to put non-function definitions in a header file. For example, C++ will let you create your own types. These user-defined types are typically defined in header files, so the definition can be propagated out to the code files that need to use them. Without a header guard, your code files can end up with multiple identical copies of these definitions, which will cause a duplicate definition compilation error.
So even though it’s not strictly necessary to have header guards at this point in the tutorial series, we’re establishing good habits now, so you don’t have to unlearn bad habits later.
#pragma once
Many compilers support a simpler, alternate form of header guards using the #pragma directive:
1 2 3 |
#pragma once // your code here |
#pragma once
serves the same purpose as header guards, and has the added benefit of being shorter and less error-prone.
However, #pragma once
is not an official part of the C++ language, and not all compilers support it (although most modern compilers do).
For compatibility purposes, we recommend sticking to traditional header guards. They aren’t much more work and they’re guaranteed to be supported on all compliant compilers.
Summary
Header guards are designed to ensure that the contents of a given header file are not copied more than once into any single file, in order to prevent duplicate definitions.
Note that duplicate declarations are fine, since a declaration can be declared multiple times without incident -- but even if your header file is composed of all declarations (no definitions) it’s still a best practice to include header guards.
Note that header guards do not prevent the contents of a header file from being copied (once) into separate project files. This is a good thing, because we often need to reference the contents of a given header from different project files.
Quiz time
![]() |
![]() |
![]() |
TYPO ERROR
need to use them them. = Two "them".
:)
I fixed them them. :) Thanks!
Hi!
I thing this is the best place to place this comment.
I'm having trouble with my header file Header.h:
Extra.cpp:
And Blankslate.cpp:
I keep getting the errors:
1>Extra.obj : error LNK2005: "int birb::thing" (?thing@birb@@3HA) already defined in BlankSlate.obj
1>C:\Users\Bastiaan\source\repos\BlankSlate\Debug\BlankSlate.exe : fatal error LNK1169: one or more multiply defined symbols found
And if I comment out the #include "Header.h" in Extra.cpp the errors disappear.
I just don't understand why, I thought you could include headerfiles in multiple code files?
Can't you?
You can, but you can't define a variable twice.
If you include "Header.h" in 2 files, and `thing` is defined in "Header.h", `thing` will be defined once by "Blankslate.cpp" and once by "Extra.cpp".
You can declare `thing` `extern` and define it in "Extra.cpp".
`constexpr` variables can be defined multiple times, that's why `gravity` doesn't cause you trouble.
Perfect, thanks!
Thank you for clear explanation.
"Header guards are designed to ensure that the contents of a given header file are not copied more than once into any single file.
Note that header guards do not prevent the contents of a header file from being copied (once) into separate project files.
There are quite a few cases we’ll show you in the future where it’s necessary to put non-function definitions in a header file."
Then we'll may have the same definition in multiple files which it's fine for compiler but not for the linker. How do we resolve this issue?
Not everything is affected by the one-definition-rule. For example classes and inline entities can be defined multiple times in separate files.
Can you please give an example?
Thanks
a.hpp
b.cpp
c.cpp
Hi! In this lesson you're using square.cpp as an example with the following contents:
I understand that not including the associated header file isn't a problem here but shouldn't this lesson conform to the best practice established in the previous lesson (2.11)?
Yup, I missed updating that example. Thanks for pointing this out. It's fixed now.
Thanks for the advice regarding the compatibility of "pragma once". Now it makes more sense to know when to use it.
Hi again. Regarding header guards on non-function definitions in header files (such as, user defined types), I understand the compiler will complain if duplicate definitions are found. But why is the linker more lenient in this case?
You had said previously that, after the pre-processor acts on a code file, the final outcome does not contain any pre-processor directives because the compiler won't understand them.
But, under the title "Updating our previous example with header guards", you showed a program containing the directives after having gone through the pre-processing phase. Kindly explain.
The example shows the code after resolving #includes, not after fully preprocessing.
I see. Wouldn't it be more complete if you mentioned in main.cpp the guard (imported from geometry.h) around the second inclusion of the content from square.h?
I agree, let's wait until @Alex sees your comment.
Agreed. Lesson updated. Thanks for your feedback!
When are should we be using the stdafx.h file?
It is mentioned in some of the lessons.
I haven't been including it and my programs work fine.
stdafx.h is no longer used. It was used by vc++ (The compiler used by Visual Studio) to speed up compilation. It has been replaced by pch.h.
If you're not using VS, you don't need it. If you're using VS, disable precompiled headers and remove the include to allow cross-platform compatibility.
Hi!
I have a doubt regarding including iostream header file in main function and another function which is called from main.
Eg:
This is the main function.
Now my getUserInput function is :
Since both of the files include iostream, will there be a conflict due to multiple definitions at linking stage?
Hi!
No, it's fine. You can include headers as many times as you want. Alex talks about why this works later in the tutorials.
Thanks a lot!
You guys are awesome. This is the complete guide to master this language. Thanks for sharing the content.Cheers!!
This is one of the best c++ tutorials site I have seen.
Hello the quiz question answer is in the text already and it has been explained before
Thanks, quiz removed until I can think up a new one.
I'm having trouble understanding the point of the forward declaration in square.h, could someone help explain that to me? Thanks
Hi Timothy!
Without the forward declarations, @main.cpp wouldn't know about the functions in @square.cpp
Alex, i don't normally comment on stuff online but this tutorial is awesome, of all the cpp tutorials I've searched up this one was by far the easiest to follow and didn't overwhelm me with 9 billion words per page. 10/10 would recommend.
I try to keep the word count to less than 1 billion words per page.
Thanks for visiting!
Hi ALEX,
CAN I SCREEN-RECORD CERTAIN PAGES FOR PERSONNEL USE ?
THANKS FOR THIS AWESOME WEBSITE....
Yes, you can do whatever you want with the content of the site for personal use only. It's redistribution or rebroadcasting that's harmful.
Hi there Alex! I am not able to understand the difference between declarations and definitions..
In the code:
Shouldn't that be a declaration? Or am I wrong?
* If you're actually allocating memory for something, it's a definition and a declaration.
* If you're just telling the compiler about the existence of something (e.g. a new type, a forward declaration) that you're going to use later, it's a pure declaration.
When you see int x used to create a local variable, that's acting as both a declaration and a definition. Because it's a definition, it's susceptible to the one definition rule. Thus, if you try to define int x; again in the same scope, you'll get an error.
But Am I not just telling the compiler about the existence of the integer x? How is it both a declaration and a definition?
also reserves space to store @x, you'll learn how to declare variables without defining them later on.
"Main.cpp is able to call this function (even though it lives in square.cpp) because it includes square.h, which has a forward declaration for the function (the linker will connect the call to getSquareSides() from main.cpp to the definition of getSquareSides() in square.cpp)."
It doesn't work for me. I have gcc compliant c++11. square.cpp must be included also in main.cpp, otherwise the program do not find the definition of functions defined (not just declared) in square.cpp
Hola amigo!
Don't include source files. Tell your compiler to compile both files at the same time.
For g++ the syntax is as follows, other compilers are similar
It's a bit late but HAPPY ANNIVERSARY! Your site is the best, sir!
I think to know how c++ doesn't work really deepen my understanding more than learning how it works
Hello Alex,
Don't you think we should now stick to #pragma once, just to make sure the code is readable, short and less error-prone?
Most of the compilers these days have support for #pragma once.
Regards,
Ishtmeet.
I generally try to recommend practices that are an official part of the C++ language, not compiler-specific extensions, even if they are widely adopted.
I wish C++ would formally adopt #pragma once because it is better than explicitly specifying header guards. But until they do, I won't recommend it, because it may leave your program unable to be compiled on particular compilers.
For what it's worth, the Google C++ style guide also recommends avoiding #pragma once.
Sorry if it's a noob question...
I'm confused about this code:
The preprocessor will look file by file and copy the contents of #includes inside each one that is doing a #includes right?
So when geometry.h does a #include "math.h", it copies to it the: int getSquareSides() definition right?
And when main.cpp does a #include "math.h" and #include "geometry.h", it is ALSO including int getSquareSides() definition right?
Shouldn't the linker complain about this duplicate definition? Or the geometry.h won't copy the contents of math.h to itself?
Help me find out what I'm missing here. Thanks.
Hi Paulo!
There's no duplicate definition, I've shown the include steps in this comment
http://www.learncpp.com/cpp-tutorial/1-10a-header-guards/comment-page-3/#comment-322851
"Now, when main.cpp #includes “math.h”, the preprocessor will see that MATH_H hasn’t been defined yet. The contents of math.h are copied into main.cpp, and MATH_H is defined. main.cpp then #includes “geometry.h”, which just #includes “math.h”. At this point, the preprocessor sees that MATH_H has previously been defined, and the contents between the header guards are skipped."
How can the preprocessor see that MATH_H has already been defined if there is no header guard for MATH.H in GEOMETRY.H?
Hi!
Let's look at what happens when the files have been included:
Now, walk through the code line by line
So the final code looks like this
Hi nascardriver,
Please allow me to make up a similar example. What does the final code look like? and What is the output? Thank you.
#ifndef MATH_H // MATH_H isn't yet defined,
#define MATH_H // so we define it and go on.
std::cout << "AAA" << std::endl;
#endif // MATH_H
#ifndef GEOMETRY_H // GEOMETRY_H isn't yet defined,
#define GEOMETRY_H // so we define it and go on.
std::cout << "BBB" << std::endl;
#ifndef MATH_H // MATH_H is already defined
#define MATH_H // This code won't be compiled
std::cout << "AAA" << std::endl;
#endif // MATH_H
#endif // GEOMETRY_H
int main()
{
std::cout << "CCC" << std::endl;
return 0;
}
Doesn't compile so no output.
You can check this yourself by generating pre-processed files. For g++ the command is
-E Stop after preprocessing
-o Output file
Output for your code
Dear Teacher, please permit me a suggestion: In program
change second return value to some number different than 5, to be clear that problem is same name of functions. Regards.
It's actually better the way it is. If I changed it, people might assume the compiler only complains if the function definition is different. In fact, the actual definition content don't matter -- it's the fact that there's more than one definition (duplicate or not) that's the issue.
Dear Teacher, please let me following question.
Header guards prevent duplicate header files. Is there way for prevent duplicate function declaration?
No. Duplicate function declarations aren't a problem:
However, Duplicate function definitions are a problem. You can generally avoid that by ensuring you define all your functions in .cpp files.
How come square.cpp doesnt require that you forward declare the function when it compiles or am I forgetting or confusing something?
// It would be okay to #include square.h here if needed
// This program doesn't need to.
int getSquareSides() // actual definition for getSquareSides
{
return 4;
}
int getSquarePerimeter(int sideLength)
{
return sideLength * getSquareSides();
}
bcoz square.cpp is a different .cpp file and it doesn't include main function which requires forward declaration to compile if functions are defined after main()...
for example
Dear Teacher,
Please let me ask you whether following source code is valid c++'s iostream header file. Symbols //@ and /// are confusing me. Former is before second "{" and before first "}".
Regards.
Hi Georges!
There is no such thing as 'the iostream header', there are many different versions of it.
What you posted matches the iostream header installed on my system.
Dear nascardriver, please accept my thanks for you replied, and for your helpful answer. I understand that what I posted is just a version of "iostream" header file. Regards.
Anything that starts with // is a single line comment, so //@ is a comment, as is ///. Why they did this, I have no idea.
Dear Teacher, please accept my many thanks for you replied, and for your helpful answer.
Please let me say you another thing I do not understand. I understand that outer body {} belongs to function
but what about inner body {}?
Regards.
I'm not sure why they put those objects inside an inner block.
Dear Teacher, please accept my thanks for you replied, and for your motivating answer. It is motivation for me, for learn c++ object and block. Regards.
What's the difference between .h and .cpp files? Can we write code inside .h files too (as in the third example)?
Hi gSymer!
You can write code inside header files, but that's not what they're meant for.
Declarations go in header files and definitions in source files.
Dear Teacher, please let me say that word pragma is transliteration of greek word πραγμα. In general it means "thing" or "stuff". For more information see at
http://www.wordreference.com/gren/%cf%80%cf%81%ce%b1%ce%b3%ce%bc%ce%b1
Regards.
Dear Teacher, please let me say that in section "Header guards do not prevent a header from being included once into different code files", in second (correct) program (project) in main.cpp file, comment is
I think correct is
By the way, color is not the usual green but same as #include ... Regards.