Search

1.10a — Header guards

The duplicate definition problem

In lesson 1.7 -- Forward declarations and definitions, we noted that an identifier can only have one definition. Thus, a program that defines a variable identifier more than once will cause a compile error:

Similarly, programs that define a function more than once will also cause a compile error:

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 example:

math.h:

geometry.h:

main.cpp:

This seemingly innocent looking program won’t compile! The root cause of the problem here is that math.h contains a definition. Here’s what’s actually happening. First, main.cpp #includes “math.h”, which copies the definition for function getSquareSides into main.cpp. Then main.cpp #includes “geometry.h”, which #includes “math.h” itself. This copies 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:

Duplicate definitions and a compile error. Each file, individually, is fine. However, because main.cpp #includes two headers that #include the same definition, we’ve run into problems. If geometry.h needs this constant, and main.cpp needs both geometry.h and math.h, how would you resolve this issue?

Note that it’s not just variable definitions that can cause this issue -- it’s any kind of definition. If math.h included a function definition, or a user-defined type, we’d run into the same problem.

Header guards

The good news is that this is actually easy to fix via a mechanism called a header guard (also called an include guard). Header guards are conditional compilation directives that take the following form:

When this header is included, the first thing it does is check whether SOME_UNIQUE_NAME_HERE has been previously defined. If this is the first time we’ve included 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 we’ve included the header before, SOME_UNIQUE_NAME_HERE will already have been defined from the first time the contents of the header were included. Consequently, the entire header will be ignored.

All of your header files should have header guards on them. SOME_UNIQUE_NAME_HERE can be any name you want, but typically the name of the header file with a _H appended to it is used. For example, math.h would have the header guard:

math.h:

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:

Updating our previous example with header guards

Let’s return to the math.h example, using the math.h with header guards.

math.h

geometry.h:

main.cpp:

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 #includes “math.h”. The preprocessor sees that MATH_H has previously been defined, and the contents between the header guards are skipped.

Thus, by adding the header guards, we’ve ensured that the contents of math.h are only included once in main.cpp.

For good form, we should also add header guards to geometry.h.

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 different code files. This can cause unexpected problems. Consider:

square.h:

square.cpp:

main.cpp:

Note that even though square.h has header guards, the contents of square.h are included once in square.cpp and once in 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!

There are multiple ways to work around this problem. One way is to put the function definition in one of the .cpp files so that the header just contains a forward declaration:

square.h:

square.cpp:

main.cpp:

Now function getSquareSides() has just one definition (in square.cpp), so the linker is happy. 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).

We’ll explore other ways to solve this problem in future lessons.

#pragma once

Many compilers support a simpler, alternate form of header guards using the #pragma directive:

#pragma once serves the same purpose as header guards, and has the added benefit of being shorter and less error-prone. The stdafx.h file that Visual Studio includes in projects that use precompiled headers makes use of this directive in place of header guards.

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 header guards.

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 don’t cause the same kinds of problems 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 different project files. This is a good thing, because we often need to reference the contents of a given header from different project files.

Quiz

1) Using the math.h example above, add header guards to file geometry.h

Show Solution

1.10b -- How to design your first programs
Index
1.10 -- A first look at the preprocessor

77 comments to 1.10a — Header guards

  • Ray

    I have a question about header guards…borrowing from the above examples if we define:

    add.h

    subtract.h

    and with main.cpp including both:

    won’t we still have the exact same problem, ie add.h and subtract.h both still bring in a copy of myMath.h and the compiler will still complain?

    Thanks,
    Ray

    PS-Thanks for putting this tutorial up, its easily the best I’ve seen on the web

    • Ray

      Never mind i just figured it out…if we use the header guards for every header, in the above example this will include the myMath.h, then when we try to bring in the myMath.h headera second time, MYMATH_H will already be defined (from the first time it was brought in) and the #ifndef statement will not allow for whatever is in myMath.h to be brought in a second time…thats pretty neat.

      Thanks again
      Ray

      [ You got it. -Alex ]

      • Noha

        I just paid attention that your question is close to the question I posted.
        You say “#ifndef statement will not allow for whatever is in myMath.h to be brought in a second time”, you mean that #ifndef MYMATH_H is needed before every #include of add.h and subtract.h?

        • Matt

          The idea is that myMath.h would have a header guard of MYMATH_H, after the first include it would define MYMATH_H and allow the first myMath.h to compile. When it was included the second time MYMATH_H would already be defined from the first call to myMath.h, so it would not compile the second instance of the include.

          tl;dr: The header guard for myMath.h (MYMATH_H) is not needed in add.h or subract.h, it’s needed in myMath.h

  • retro-starr

    Is there anything wrong with typing the headers in lowercase and with spaces (I still use underscores though)? I tested it out earlier when I was making another program that used a header and it still worked. If there’s nothing wrong, I stylistically like the lowercase.

    • Alex

      There’s nothing syntactically wrong (it will work fine), but convention specifies that #defined values are done in upper case with underscores. It’s up to you if you want to follow convention.

  • I’m confused, how does it know if the header has already been declared?
    For example, if it says

    in the header file, how does it know if add.h is declared since they are not the same?

    • Okay never mind. Correct me if I’m wrong:
      All the header files will have

      so that if the header is not included, then SOME_UNIQUE_NAME_HERE will not have been defined.
      “Your declarations here” will be the “include”‘s of headers, and “stuff” should be the code of the header? Thanks.

      • Alex

        Right, if the header hasn’t been included yet, then SOME_UNIQUE_NAME_HERE will not have been defined.

        I don’t know what //stuff is supposed to be. There should be nothing after the end of the header guard (the #endif declaration).

  • David

    I love this tutorial!!!

  • Eric

    I guess my question is: why would a header file need to include a different header file if all header files contain are declarations? Is this something you only encounter once you are writing bigger programs? I understand including header files in places where you are using functions defined in external files to avoid writing a ton of forward declarations, but can someone give me an example that wouldn’t be completely over my head of a header needing to include another header? Thanks!

    • Alex

      This is a great question. It’s actually _very_ common for header files to include other header files.

      You’re correct that header files typically only include declarations. At this point in the tutorials, you’ve only seen one type of declaration: function declarations. However, there are other kinds of declarations (like types and classes) that also live in header files.

      Probably the most common example is with strings. A string is a sequence of characters, like “Hello, world!” or “abcdefg”. C++ doesn’t include very good built-in support for working with strings. The C++ standard library comes with a header file named “string” that includes declarations for a class called “string” that makes it much easier to work with strings.

      So if you want to use std::string (e.g. as a function parameter, or return type), you need to include the string header.

      e.g.

      Even though we haven’t discussed classes or std::string yet, hopefully this makes sense.

  • alienbeliever

    This tutorial is so well structured and understandable that it blows my mind. Thanks A LOT. It´s an outstanding work of love. KUDOS!

  • lackadaisy

    I just wanted to leave a note saying this is the most amazing tutorial ever. I hated programming but I think I might start liking it quite a bit now because I finally understand it!

  • Maverick95

    I’m failing to see why I need to use header guards with the IDE that I’m using.
    The code below I’ve used in Microsoft Visual C++ 2010 Express and it compiles without any complaints or errors.

    NumericOperations.h

    int add(int x, int y);
    int subtract(int x, int y);

    PrintAdd.h

    #include "NumericOperations.h"

    #ifndef PRINTADD_H
    #define PRINTADD_H

    void PrintAdd(int x, int y);

    #endif

    PrintSubtract.h

    #include "NumericOperations.h"

    #ifndef PRINTSUBTRACT_H
    #define PRINTSUBTRACT_H

    void PrintSubtract(int x, int y);

    #endif

    HeaderGuardTest.cpp

    #include "stdafx.h"
    #include "PrintAdd.h"
    #include "PrintSubtract.h"
    #include "KeyFunctions.h"

    I should note that all the functions above have been defined in .cpp files.

    My code compiles successfully, but I have included NumericOperations.h twice. Shouldn’t this give me an error?

    • The #ifndef ensures that everything required is initialized once and no more. When you load it the second time, the compiler sees that the variables and whatnot have been declared, so it does nothing.

    • Alex

      Declarations can be included more than once, so if your header file includes only declarations, then it can be included more than once without issue. We only run into problems with definitions.

      Once you get into object-oriented programming, most header files will contain at least one definition.

      • Anlam K.

        "Declarations can be included more than once, so if your header file includes only declarations, then it can be included more than once without issue."

        I think you should make this explicit in the tutorial. I was confused until I read this.

  • dice3000

    I believe that [ #pragma once ] serves the same purpose as header guards

    • Alex

      It does, on compilers that support it.

      The problem is that #pragma once isn’t officially a part of the language, and not all compilers support it (even though many modern ones do). Google’s C++ style guide explicitly tells Google developers not to use #pragma once, so we’re following suit here and not recommending its use.

      • Jimbo

        Does that mean my project won’t be compatible by default? In Visual C++ 2015 the stdafx.h header is by default using the #pragma once instead of #ifndef and I’m calling it in every .cpp file.

  • rdewji

    When creating header files, you can add them to the “source files” folder, or the “header files” folder (by right-clicking on the respective folders). Other than organization (in that all the header files should be in the “header files” folder), is there any reason to choose one or the other? The first question that comes to my mind is whether it affects the speed of the program in any way. (Or even if so, would it only affect the speed of compiling, and not of running the program?)

  • liyuan

    I dont understand one thing. If header files only contain declarations why do you need header guards? I’ve tried having multiple lines of declarations of the same function and my code blocks has no problem compiling the code. in the tutorial you gave an example of a header file containing a definition but aren’t definitions supposed to be in cpp files? hope you can clarify 🙂

    • Alex

      Good question. The short answer is that header files can contain both declarations and definitions, and the compiler will complain if you have more than one definition for an identifier, even if it’s identical to the previous one.

      If your header file contained nothing but pure declarations, then header guards technically wouldn’t be necessary (but I’d still add them anyway for safety).

  • Jim

    Alex,
    It seems to me that a lot of extra work is being done to make header guards and header files and then adding all this to each function including main and make sure all of this is done correctly where needed.

    I think it would be much easier just to copy and paste the function declaration part if every function like, int add (int x, int y), back into add.cpp and make it a prototype with the semicolon after it. Then save it. If you want to use any function like add.cpp in any program you just insert it into the IDE and cut and pasted the prototype section into main.cpp and your done.

    Of course you just need to make it a habit with ever function. Then you can use that function in any program and any number of time you want without a problem.  This seems a lot simpler to me.

    • Alex

      It might seem simpler now, because we are dealing with simple examples. As programs get more complicated, the method you propose above won’t scale.

      I’m not making you do extra work because I want to see you suffer. 🙂 I’m trying to set you up with good habits now so that when we get to more advanced topics and have programs that span multiple files and have many functions, you’ll understand how to write programs that are easily extensible, and so that you can package up things into easily reusable pieces.

  • Sharaf

    is header guard only for programs which have a muliple file, if not can you make a single program to illustrate the mymath.h, add.h, subtract.h, main.cpp….. or any other explaining the use of header guard… and why you have changed mymath to MYMATH…
    i couldn’t compile the program because i coudn’t make multiple filed program………. i am getting error as “anyname() not found in directory”
    and sorry for this stupid question why you have used a particular use of #ifndef and #define

    • Alex

      Header guards are for header files, regardless of how many files are in your program.

      It’s convention to use all caps for #define values, presumably to differentiate them from variable and function names.

  • Zuy

    Hi Alex , thanks again for the amazing lessons. I have a problem while following the example on header guard above. Here are what I wrote for the whole thing:

    add.h :
    #ifndef ADD_H
    #define ADD_H

    #include "mymath.h"
    int add(int x, int y);

    #endif

    add.cpp :
    #include "stdafx.h"
    #include "add.h"

    int add(int x, int y)
    {
        return x + y;
    }

    subtract.h :
    #ifndef SUBTRACT_H
    #define SUBTRACT_H

    #include "mymath.h"
    int subtract(int x, int y);

    #endif

    subtract.cpp :
    #include "stdafx.h"
    #include "subtract.h"

    int subtract(int x, int y)
    {
        return x - y;
    }

    mymath.h :
    #ifndef MYMATH_H
    #define MYMATH_H
    int cardsInDeck()
    {
        return 52;
    }
    #endif

    main.cpp :
    #include "add.h"
    #include "subtract.h"

    int main()
    {
        return 0;
    }

    When I tried compiling the programme , there are 3 errors:
    -LNK2005    "int __cdecl cardsInDeck(void)" (?cardsInDeck@@YAHXZ) already defined in add.obj    Preprocessor and Header guards    C:\Users\User\Documents\Visual Studio 2015\Projects\Preprocessor and Header guards\Preprocessor and Header guards\subtract.obj    1    
    -LNK2005    "int __cdecl cardsInDeck(void)" (?cardsInDeck@@YAHXZ) already defined in add.obj    Preprocessor and Header guards    C:\Users\User\Documents\Visual Studio 2015\Projects\Preprocessor and Header guards\Preprocessor and Header guards\main.obj    1    
    -LNK1169    one or more multiply defined symbols found    Preprocessor and Header guards    C:\Users\User\Documents\Visual Studio 2015\Projects\Preprocessor and Header guards\Debug\Preprocessor and Header guards.exe    1    

    I am not sure which part is wrong, I tried to follow the example as closely as I could. I’d be very appreciated if you could help me point out the mistake. Thanks again Alex!

    • Alex

      Ah, you’ve encountered a bit of trickiness. Your header guards _ARE_ working properly.

      The problem here is that we’ve defined function cardsInDeck() in the header file. Since mymath.h is #included once in add.cpp and subtract.cpp, each gets a copy of the definition of cardsInDeck(). The compiler is complaining about the fact that the function definition for cardsInDeck() lives in two different places.

      The solution is easy: move the body of cardsInDeck() to a .cpp file (any .cpp file) and leave just the prototype in the header.

  • Shiva

    Hey Alex, revisiting this lesson, I noticed a small typo:

    > Many compilers support an (a) simpler, alternate form of header guards using the #pragma directive

    Keep up the good work. 🙂

  • siva

    Hi Alex ,

    I have a basic doubt .

    Ex.h
    =====
    #ifndef EX_H
    #define EX_H
    int gv=20;
    #endif

    Ex.cc
    =====
    #include <iostream>
    #include "Ex.h"
    using namespace std;
    extern int fn1();
    int main()
    {
          cout<<"in ex"<<gv<<endl;
          fn1();
          return 0;
    }

    Ex1.cc
    =======
    #include <iostream>
    #include "Ex.h"
    using namespace std;

    int fn1()
    {
          cout<<"in ex1"<<gv<<endl;
          return 0;
    }

    I am getting the below error,
    /tmp/cc33pWKE.o:(.data+0x0): multiple definition of `gv’
    /tmp/ccSgCloS.o:(.data+0x0): first defined here
    collect2: ld returned 1 exit status

    Cant we include same header file in two .cc files ??

    • Alex

      You can definitely include the same header file in two (or more) code files.

      The problem here is that you’re defining a variable in a .h file (which is generally a bad idea). Since both ex.cc and ex1.cc include this header, both end up getting a copy of this definition as a global variable. Non-const global variables have external linkage by default (see lesson 4.3a -- Scope, duration, and linkage summary), so these two instances of the variable see each other and conflict.

      • siva

        Hi Alex,

        I am just trying to understand this linkage concept.
        Here,
        Ex.h
        =====
        #ifndef EX_H                   ====> Wont this restrict the defn to only once ?
        #define EX_H
        int gv=20;
        #endif

        How come two instances will be produced.
        Is the pre processor header guard getting  overridden ?

        • Alex

          If you haven’t already gotten to chapter 4, don’t worry about linkage for now.

          The short answer is already in the conclusion of this lesson: “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 header guards do not prevent the contents of a header file from being copied (once) into different project files.”

          What you have here is the case where a header is being included once into two different files. That is fine, and header guards are not meant to stop this case from happening. You’re running into a problem because you have a variable definition in your header. For now, if you only put declarations in your headers (no definitions) you can avoid these kinds of things.

  • siva

    Thanks for your help..understood the concept:D

  • J3ANP3T3R

    every time we add a new header to the project the IDE automatically adds
    #pragma once

    on top of the contents of the newly created header. since it is recommended to stick to the header guards should we remove "#pragma once" every time and replace it with header guards ?

    i am using visual studio 2015

  • Varun

    Somehow I managed to get this error when trying to compile the example with the square sides thing. Not entirely sure how I got here though. what does this mean?

    Error    C1853    ‘Debug\Squares.pch’ precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa)    Squares    c:\vc2005projects\squares\squares\square_perimeter.c    1

    • Alex

      That’s a new one on me.

      Try doing a clean build (Build->Clean Solution, then rebuild) and see if that cleans things out. Maybe you got a corrupted file somehow.

  • Bob

    I get multiple definition of ‘getSquareSides()’ compile error, please help

    • Alex

      Yup, the example was incorrect. I’ve replaced it with another example that I think does a better job of illustrating what header guards don’t protect against, and how you can fix that case. Have a read and let me know whether it makes sense, or if there is something else I can clarify.

  • Darren

    One problem with header guards is the naming of the macro identifier. It is not inconceivable that two programmers working on two separate but related projects, say interdependent libraries, may have identical names for a header file. This naming clash would mean that if these header files are included in the same source the one that was included second would have its contents skipped. A sensible suggestion would be to embed some random characters in the header guard name that would make it unique. An approximation to that uniqueness would be, say, the programmers initials or the project name/acronym.

  • Zachary

    So as a general rule of thumb, wouldn’t it be best to just exclude definitions from headers and only make forward declarations within a header file?

    • Alex

      Yes, generally speaking, you should try to exclude definitions from headers wherever possible. And this isn’t that hard when it comes to variable or function definitions.

      However, for type definitions (where you are defining your own custom types) this is often not possible, as the code using the type in most cases needs to know the type definition, not just a declaration. This is a particularly common issue in object-oriented programming.

  • fearless

    Hi Alex, Thanks for this wonderful tutorial site!
    i have a question
    in this particular code, the linker will complain about getSquareSides() is being defined twice. But isn’t square.h is only being defined once in main.cpp. Is it still being defined in square.cpp even though it is already being defined in main. Shouldn’t square.cpp’s square.h skip the define process when #ifndef SQUARE_H is processed?

    square.h:
        
    #ifndef SQUARE_H
    #define SQUARE_H

    int getSquareSides()
    {
        return 4;
    }

    int getSquarePerimeter(int sideLength); // forward declaration for getSquarePerimeter

    #endif

    square.cpp:
        
    #include "square.h"  // square.h is included once here

    int getSquarePerimeter(int sideLength)
    {
        return sideLength * getSquareSides();
    }

    main.cpp:

    #include "square.h" // square.h is also included once here

    int main()
    {
        std::cout << "a square has " << getSquareSides() << "sides" << std::endl;
        std::cout << "a square of length 5 has perimeter length " << getSquarePerimeter(5) << std::endl;

        return 0;
    }

    • Alex

      No. #ifdefs are only good for the given file. They do not carry over to other files. So when main.cpp includes square.h, SQUARE_H is defined. But then main.cpp finishes compiling, and SQUARE_H is no longer considered defined. So by the time it starts compiling square.cpp, SQUARE_H is no longer considered defined, and the contents of square.h get included.

  • Hello! There’s a problem in this line of code:

    There should be no

    ! 🙂

    Also, where you say:

    Shouldn’t it be as follows?:

    Thanks! Nice tutorials!

  • Timmy

    Ok, I have a problem. I have declared a function twice in a project and it seems to work. I can’t figure out why. Here are my files:

    main.cpp

    add.h

    add2.h

    I also have defined the add function in another file and I am not using header guards.
    I thought that this should not work because I have declared the add function within the add.h header and the add.h file is included in add2.h file, therefore the function add.h is declared twice!
    An explanation for this would be appreciated 🙂

    P.S. I’ve also tried using two exactly the same #includes for add.h in the same file and that also worked. Don’t know if the preprocessor just ignores the same two #includes or is this related to the same issue as above.

    • Alex

      There’s nothing in C++ that says you can’t have more than one declaration for the same thing. In add.h, you only have a function forward declaration, so there’s no problem with this getting included twice.

      However, you can only have one definition. If you were to move the function definition for function add() into add.h, you’d see that the compiler or linker would complain about duplicate definitions.

      • Timmy

        Thanks for clearing things up! Just just tested this with the definition of add function in the header file and everything is as expected.

  • Dinesh

    Hi Alex your tutorial is truly amazing.I just have one request.
    Can u give us more quiz programs to work with?
    I mean some twisty programs to give us a challenge.
    All programs i try myself are all linear and doesnt provide any challenge.
    Thanks in advance 🙂

  • Tristan Gybels

    square.h

    square.cpp

    maina.cpp

    1>c:usersgebruikerdocumentsvisual studio 2015projectsmainamainasquare.cpp(8): error C2065: ‘sides’: undeclared identifier
    Can someone tell me why this isn’t correct?

    • Alex

      It’s complaining about:

      You never defined what sides is for this function.

  • bert

    Did you mean to use "being" in the following line?

    "This define prevents square.h from be included into square.cpp a second time"

    Thanks! It’s been a very enjoyable read so far.

  • vishwesh

    Hi Alex,
    I have a question from this example that you have here:
    [code]
    square.h:
    #ifndef SQUARE_H
    #define SQUARE_H

    int getSquareSides(); // forward declaration for getSquareSides
    int getSquarePerimeter(int sideLength); // forward declaration for getSquarePerimeter

    #endif
    square.cpp:
    #include "square.h"  // square.h is included once here

    int getSquareSides() // actual definition for getSquareSides
    {
        return 4;
    }

    int getSquarePerimeter(int sideLength)
    {
        return sideLength * getSquareSides();
    }
    main.cpp:

    #include "square.h" // square.h is also included once here

    int main()
    {
        std::cout << "a square has " << getSquareSides() << "sides" << std::endl;
        std::cout << "a square of length 5 has perimeter length " << getSquarePerimeter(5) << std::endl;

        return 0;
    }
    [\code]
    In this code, why must we include "square.h" in the square.cpp file? I understand that function declaration must be made before it is used in the main.cpp file, but what’s the need to declare the function before defining it in the square.cpp file?

    • Alex

      In this example, it’s not strictly necessary, since square.cpp doesn’t depend on anything in square.h (we would need it if we had defined getSquarePerimeter() before getSquareSides()).

      However, it’s pretty common to have something in the .cpp file depend on something in the .h file, particularly when we get into object oriented programming.

      • Nguyen

        Hi Alex,

        You said that we would need it if we had defined getSquarePerimeter() before getSquareSides().

        Here below are what I understand from what you said.  

        square.cpp:
        #include "square.h"  // square.h is included once here

        int getSquarePerimeter(int sideLength)
          {
             return sideLength * getSquareSides();
          }

        int getSquareSides() // actual definition for getSquareSides
          {
             return 4;
          }

        If getSquarePerimeter() and getSquareSides() just switch their location, I am not sure why #include "square.h" is needed.

        Sorry for my bad English.  I hope you understand.

        • Alex

          The compiler compiles code in order from the top to the bottom of the file.

          If you don’t include square.h, when the compiler compiles getSquareParameter(), it would see the call to getSquareSides(). It would then say, “hmmm, I’ve never seen that function before, that must be an error”.

          However, with square.h included, the forward declaration for getSquareSides() in square.h tells the compiler that getSquareSides() should be treated as a valid function, even if it hasn’t seen the definition yet.

  • HWANG SEHYUN

    Thanks you every time. I have a question about the case when "Header guards do not prevent a header from being included once into different code files". I conceptually understood the situation but I wondered how main.cpp include other cpp file. When it comes to header file it is straight forward because when header file(for example square.h) included into the main.cpp, the contents square.h(which is declaration) would just copied into the main.cpp. However when using different cpp files, the linker will link object files of these different cpp file.
    In summary my question is this. When square.h is included once in a main.cpp and square.cpp how will they cause trouble?

    • Alex

      This is already answered in the “Header guards do not prevent a header from being included once into different code files” section.

      In the example there, the contents of square.h is copied into both square.cpp and main.cpp. Both of these files are compiled individually, and compile file. Then the linker runs. At this point, the linker will notice that both square.cpp and main.cpp have a function named getSquareSides(). This will cause the linker to error out with a duplicate definition error.

  • RasmoLaxsus

    ok lets say a there is chem.h and bio.h files.

    chem.h contains:

    bio.h contains:

    both of these have header guards. If they are included into main like this;

    does this mean that chem.h will be ignored since it contained { int add (int x) } hence { int subtruct (int x) } will not be declared in main ?

    • Alex

      No. It means main.cpp will get two copies of the declaration for function add() (one from chem.h and one from bio.h). In this case, that won’t be a problem since these are just declarations, and C++ allows duplicate declarations. You only get into trouble when you have duplicate definitions (e.g. if add had a function body).

  • Foster

    Hi Alex, I have been enjoying these tutorials but the header guards I am running into a bit of a large troubleshooting problem.

    I have tried to recreate square.h square.cpp and main.cpp  and I am running into an issue starting from square.h which propagates through the rest of my code.

    square.h

    square.cpp

    main.cpp

    the biggest problem that is happening (which I am sure is a simple fix but I can not figure out) is VS is telling me that "IntelliSense:cannot open source file "square.h" ". In addition I made sure to bring in the square.h file into the header file folder of Main.cpp, and I brought Square.cpp into the source file folder of Main.cpp, so I do not know why it says it can not open source file.

    Thank you for all you help!!

    • Alex

      I’m not sure. Maybe the #include “stdafx.h” inside square.h is confusing it? Generally you should only #include “stdafx.h” from .cpp files, not from header files. Try removing that line and see if it helps.

  • Matt

    Typo at the end of "Header guards". You wrote:
    "Even the standard library includes use header guards."

  • My dear c++ Teacher,
    Please let me say something trivial. In last main.cpp file, #include <iostream> should be included for program run.
    With regards and friendship.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter