C++ headers inclusions

Alexandre Toqué

I am working on a project, each header file has a preprocessor include guard. My includes are made like this:

(file -> includes)

main.cpp -> header.h; Character.h

header.h -> vector, iostream, ... , DataFiles.h

Character.h -> DataFiles.h, header.h, CharFrame.h

CharFrame.h -> DataFiles.h, header.h

Everything work fine. But if I just erase the main.cpp's #include "Character.h" to move it in header.h, I get lots of errors at compilation. So now it is:

main.cpp -> header.h

header.h -> ... , DataFiles.h, Character.h.

What's the difference?

Here is my compilator output:

Inspiron-1545:~/Desktop/LF2_linux$ g++ -Wall main.cpp DataFiles.cpp header.cpp Character.cpp CharFrame.cpp -lSDL -lSDL_image -lSDL_ttf -o test
In file included from header.h:13:0,
             from CharFrame.h:12,
             from CharFrame.cpp:1:
Character.h:55:15: error: ‘CharFrame’ was not declared in this scope
Character.h:55:25: error: template argument 1 is invalid
Character.h:55:25: error: template argument 2 is invalid

If the include is put back into the main.cpp, then it compiles without any error.

If you feel my code IS necessary I will edit this post and paste everything.

Here are the lines of interest:

header.h:13 ->
 #include "Character.h"
CharFrame.h:12 -> 
 #include "header.h"
CharFrame.cpp:1 -> 
 #include "CharFrame.h"
Character.h:55 ->  
 std::vector <CharFrame*> *frame;
cmaster - reinstate monica

Your change created an inclusion cycle between Character.h and header.h.

Presumably, Character.h relies on some declarations in headers.h. Now, with your change, the following happens:

  1. headers.h is included, defines its include guard, and the preprocessor starts examining its contents.

  2. headers.h includes Character.h, before it makes its own declarations.

    1. Character.h defines its include guard, the preprocessor reads its contents.

    2. Character.h includes header.h to get the definitions it needs.

      1. headers.h, however sees its include guard, and is parsed as empty. No definitions are made yet.
    3. Character.h definitions are read.

  3. headers.h definitions are read.

As you can see, the definitions in Character.h are read before the definitions in header.h, which they rely upon.

The best way to fix a circular inclusion is to replace #includes with forward declarations whenever possible. In some rare cases it might become necessary to actually mix declarations with includes, but you should avoid such a thing at all costs.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related