CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    C++ Preprocessor: What is the purpose of include guards?

    Q: What is the purpose of include guards?
    Q: Why do I get the compiler error "xxx already defined" when I include my own files?

    A: In order to understand the solution, we must first understand the mechanism of how include files work. When you put a line

    Code:
    #include "myheader.h"
    in another file, then during compilation the contents of the file called 'myheader.h' will be inserted at that location. This is a simple concept but can lead to problems.

    One such problematic case is when you have three header files. Let's call them 'header_base', 'header_a' and 'header_b'. Both 'header_a' and 'header_b' include 'header_base', because they need the definitions found there. When you now include 'header_a' and 'header_b' inside a '.cpp' file, you'll most likely get a compiler error complaing about multiple definitions.

    The offending code could be structered like this:

    Code:
    // header_base.h
    class base_class
    {
      // some code
    };
    
    // header_a.h
    #include "header_base.h"
    
    class derived_a : public base_class
    {
      // some code
    };
    
    // header_b.h
    #include "header_base.h"
    
    class derived_b : public base_class
    {
      // some code
    };
    
    // main.cpp
    #include "header_a.h"
    #include "header_b.h"
    
    int main()
    {
      return 0;
    }
    When 'main.cpp' gets compiled, the contents of the header will be inserted at the appropriate locations and this will result in the following code:

    Code:
    // #include "header_a.h"
      // code for header_a.h begins
      // #include "header_base.h"
        // code for header_base.h begins
        class base_class
        {
          // some code
        };
        // code for header_base.h ends
    
      class derived_a : public base_class
      {
        // some code
      };
      // code for header_a.h ends
      
    // #include "header_b.h"
      // code for header_b.h begins
      // #include "header_base.h"
        // code for header_base.h begins
        class base_class
        {
          // some code
        };
        // code for header_base.h ends
    
      class derived_b : public base_class
      {
        // some code
      };
      // code for header_b.h ends
    
    int main()
    {
      return 0;
    }
    Now it's pretty clear that 'base_class' is defined twice and this is not legal C++. The solution is to make use of a preprocessor definition specific to the header file which guards its contents from being dumped twice into the same cpp file. An example is the following.

    Code:
    #ifndef HEADER_BASE_HPP
    #define HEADER_BASE_HPP
    
    class base_class
    {
      // some code
    };
    
    #endif // HEADER_BASE_HPP
    The first line checks whether we have not yet defined 'HEADER_BASE_HPP'. If we have not, then we define it and include the rest of the file. If it is already defined, i.e. if this header file has already been included, then we will just skip until the end of the file and nothing more will get dumped into the '.cpp' file.


    Last edited by Andreas Masur; July 23rd, 2005 at 01:36 PM.

  2. #2
    Join Date
    Oct 2002
    Location
    Timisoara, Romania
    Posts
    14,360

    Re: C++ Preprocessor: What is the purpose of include guards?

    On Microsoft compilers guarding can be done using #pragma once, as the first pre-processor directive in a header.
    Code:
    #pragma once
    
    // content of the header
    
    class base_class
    {
    };
    Marius Bancila
    Home Page
    My CodeGuru articles

    I do not offer technical support via PM or e-mail. Please use vbBulletin codes.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured