Thread: Header file include order

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    271

    Header file include order

    This is the first time I've tackled a c++ program with more than 10 files included in it, and I'm having a hard time understanding how to order the files which get included.

    I'm guessing there's a method to this madness but it's still basically a crapshoot. One thing I discovered is that the headers which tend to be used in every other header should be pushed to the bottom when being included in the source cpp file which includes main().

    And then there are the orders I don't understand.

    Let's say there's a header that's called by every other header but does not include anything itself. I'll call this "A.h". Then there's "B.h" and "C.h" which includes "A.h".
    Finally, this gets included in "main.cpp". (btw, they all have include guards). The top of "main.cpp" would look like this:
    Code:
    #include <standard c++ headers>
    #include ...
    #include "B.h"
    #include "C.h"
    #include "A.h"
    If I move "A.h" above "B.h", then I get some stupid error like this:
    Code:
    c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\assert.h(59): error C2059: syntax error : 'constant'
    c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\assert.h(181): error C2018: unknown character '0x3'
    c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\assert.h(189): fatal error C1071: unexpected end of file found in comment
    Finally, I'm trying to use the greta regular expression library. It works okay but only if I place it at the very top of the include list. I don't get it. WTF does include order have to do with how it compiles? This works but the others just give me internal compiler errors:
    Code:
    // This order works
    #include "greta/regexpr2.h"
    #include <standard c++ headers>
    #include ...
    #include "B.h"
    #include "C.h"
    #include "A.h"
    
    // This order doesn't
    #include <standard c++ headers>
    #include ...
    #include "greta/regexpr2.h"
    #include "B.h"
    #include "C.h"
    #include "A.h"
    
    // Neither does this
    #include <standard c++ headers>
    #include ...
    #include "B.h"
    #include "C.h"
    #include "A.h"
    #include "greta/regexpr2.h"
    Could somebody tell me what's going on? Or if you could point me to some coherent tutorial, that would be most helpful.

  2. #2
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    we obviously have no clue what is contained in a.h, b.h and c.h. They should contain code gards to prevent them from being included multiple times. standard c and c++ header files normally have no specific order, just include them however you wish. But if your own header files contain c++ objects defined in those headers then you may have to have the "using namespact std" line before including your own header files.

    This might be of some benefit.
    Last edited by Ancient Dragon; 05-16-2006 at 11:03 PM.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    But if your own header files contain c++ objects defined in those headers then you may have to have the "using namespact std" line before including your own header files.
    Or, better yet, you use fully qualified names in your own header files so that a using declaration is unnecessary.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Well, I've attached my entire project. It's actually a zip archive so you'll have to change the extension to .zip.

    In it, there's a header file called "stdafx.h"

    Problems arise when I try messing with the include order.

    Some that work:
    Code:
    #include "units.h"
    #include "eval.h"
    #include "phone_initialize.h"
    #include "main_header.h"
    
    OR
    
    #include "eval.h"
    #include "phone_initialize.h"
    #include "units.h"
    #include "main_header.h"
    Some that don't:
    Code:
    #include "phone_initialize.h"
    #include "main_header.h"
    #include "units.h"
    #include "eval.h"
    
    OR
    
    #include "phone_initialize.h"
    #include "units.h"
    #include "eval.h"
    #include "main_header.h"
    One that throws an internal compiler error (in spite of the fact that "ipa.h" is actually included in "phone_initialize.h"):
    Code:
    #include "ipa.h"
    #include "units.h"
    #include "eval.h"
    #include "phone_initialize.h"
    #include "main_header.h"
    So I usually just comment out the "#include "ipa.h"" part since it does get included in another header.

    It is bewildering.
    Last edited by cunnus88; 02-04-2008 at 01:12 AM.

  5. #5
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    I think I know why commenting out "ipa.h" works. I'd completely forgotten that this file was in unicode while the others weren't. But then it doesn't really make sense. It's included in "phone_initialize.h" and it doesn't cause any problems there.
    And I isolated the behavior concerning the include order errors. It gives me an error if and only if "phone_initialize.h" is placed before "eval.h".

    I looked at the code and I really don't get why this should be so.

  6. #6
    char main() RoshanX's Avatar
    Join Date
    Mar 2003
    Posts
    68
    If I understood your problem correctly, the reason is as follows. Every include file ( should ) include the following line to prevent it from including more than once in the same souce file

    Code:
    #ifndef _HEADER_FILE_NAME_H_AND_SOMETHING_ELSE
    #define _HEADER_FILE_NAME_H_AND_SOMETHING_ELSE
    
    ...
    ...
    ...
    #endif
    If you have a header file A.h who includes B.h and C.h, then the cpp ( c preprocessor) will first start from A.h, and will go to B.h and preprocess it at the point where B.h is included.
    assume your incluce files are as follows

    A.h
    Code:
    #ifndef A_H_
    #define A_H_
    #include "B.h"
    ...
    ...
    class A_A { ....};
    B.h
    Code:
    #ifndef B_H
    #define B_H
    #include "A.h"
    ...
    ...
    
    class K
    {
       A_A a;
    }
    this will not compile correctly since, when B.h is preprocessed, it will no include A.h, so the class A_A is not defined ( it gest defined later on ) ( this happens becuse of interdependancy of A.h and B.h ). To avoid this, eithe restructre the header files, or put all the includes before #ifndef ....
    First there was God. He was quite lonely, so he created Dennis.
    Dennis was unimpressed with God.
    So, . . . God created Brian..........Khan Klatt
    http://www.clifford.at/fun/GOD

  7. #7
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    My header files all have include guards and none of them cross reference each other. The structure is as follows.

    "main_header.h" defines type definitions and includes standard c++ headers, namely:
    Code:
    #include <string>
    #include <vector>
    #include <set>
    #include <bitset>
    #include <algorithm>
    #include <iomanip>
    #include <iostream>
    
    class phone;
    
    using std::string;
    using std::wstring;
    using std::vector;
    using std::set;
    using std::cout;
    using std::endl;
    using std::ostream;
    using std::bitset;
    using std::setw;
    using std::setfill;
    using std::less;
    using std::ios;
    using std::setiosflags;
    "ipa.h" includes nothing and is only a list of constant definitions. The only thing of note is that this file is in unicode (which should not be an issue for VC++2003).

    The following files include other headers of some sort:
    1. "units.h" which includes "main_header.h".
    2. "phone_initialize.h" which includes "units.h" and "ipa.h"
    3. "eval.h" which includes "units.h" and "phone_initialize.h"


    I originally defined my "stdafx.h" as follows:
    Code:
    #pragma once
    
    #include <string>
    #include <sstream>
    #include <iostream>
    #include <fstream>
    #include <bitset>
    #include <algorithm>
    #include <vector>
    #include <iomanip>
    #include <cstdlib>
    #include "eval.h"
    #include "phone_initialize.h"
    #include "main_header.h"
    #include "units.h"
    #include "ipa.h"
    But for some reason, it wouldn't compile unless I commented out "#include ipa.h". Also, it would compile if and only if "phone_initialize.h" is not placed above "eval.h".

    I guess you could say this is a trivial issue since I located the problems and got rid of it, but I have feeling this might blow up in my face someday unless I know why it's acting like this.

    So if anyone can help me, I would really appreciate it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 02-10-2009, 02:51 PM
  2. Need help understanding Header Files
    By Kaidao in forum C++ Programming
    Replies: 11
    Last Post: 03-25-2008, 10:02 AM
  3. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  4. help with finding lowest number entered
    By volk in forum C++ Programming
    Replies: 12
    Last Post: 03-22-2003, 01:21 PM
  5. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM