Click to See Complete Forum and Search --> : #include order


pavel989
July 10th, 2008, 02:41 PM
does the order of the #include directives matter? if so, why and how do you know what the order is?

cilu
July 10th, 2008, 03:34 PM
Of course it matters. It's very simple: when the pre-processor starts resolving the preprocessor directives (#include, #define), it starts from the very top of the cpp file. So the first #include is replaced with the header content. If that header contains any #include, they are replaced in the order they are found, and so on, until everything is replaced. It's like a tree evaluated infix.

Lindley
July 10th, 2008, 03:45 PM
It *shouldn't* matter, ideally, but sometimes it does.

When you encounter such a situation, you can identify it by mysterious compile errors showing up in bizarre places. The correct order is whichever one makes the compile errors go away.

TheCPUWizard
July 10th, 2008, 03:48 PM
This is actually one of the design checks we run. For all of our headers we (dynamically create a cpp that is just an include of the header in question. This must compile without error (or with an explicit "You Must Include..." error.

Althoguh this technique will NOT catch all issues, it really helps minimize them...

Lindley
July 10th, 2008, 03:56 PM
Whatever you do, don't take it upon yourself to #define anything in your headers that might also be defined in any part of the standard library. Please. I have these lines in part of my code right now:


#include "f2c.h"
#undef abs
because that's the only way I could get it to play nicely with stdlib.h.

Graham
July 10th, 2008, 04:18 PM
And remember that pre-compiled headers often have to be the first thing included. For example, VC++ (at least at v6 - I haven't tried it with later versions) will ignore everything up to the #include "stdafx.h" line if precompiled headers are turned on.

STLDude
July 10th, 2008, 06:16 PM
Whatever you do, don't take it upon yourself to #define anything in your headers that might also be defined in any part of the standard library. Please. I have these lines in part of my code right now:


#include "f2c.h"
#undef abs
because that's the only way I could get it to play nicely with stdlib.h.

And what about using different names in your library, or ditch/minimize #defines and use namespaces instead.

Lindley
July 10th, 2008, 11:20 PM
Good advice in general. Just for the record, though, f2c isn't mine. It's a common Fortran-to-C interface.

Zaccheus
July 11th, 2008, 03:04 AM
And what about using different names in your library, or ditch/minimize #defines and use namespaces instead.
A classic example of what Lindley says is the Windows API which contains #define min and #define max. That really confuses the STL when it tries to declare its min and max functions, but at least you can #define NOMINMAX before including windows.h in your code.

souldog
July 11th, 2008, 03:17 AM
#define min and #define max


I hate those two stupid evil macros. HATE HATE HATE

Zaccheus
July 11th, 2008, 03:58 AM
It gets better ...



/*
* Compatibility macros
*/

#define DefineHandleTable(w) ((w),TRUE)
#define LimitEmsPages(dw)
#define SetSwapAreaSize(w) (w)
#define LockSegment(w) GlobalFix((HANDLE)(w))
#define UnlockSegment(w) GlobalUnfix((HANDLE)(w))
#define GetCurrentTime() GetTickCount()

#define Yield()


Have fun figuring out the compiler errors if you try to declare a function with one of those names in your class.
:eek:

souldog
July 11th, 2008, 04:04 AM
HATE HATE HATE

sorry for the spam, but I really do hate

Kheun
July 11th, 2008, 07:27 AM
I always strive to write header file so that doesn't impose any requirement needing to include other header files in any specific order. At least, it save any future user the frustration of forgetting to include other files that my header file depends on.

TheCPUWizard
July 11th, 2008, 07:54 AM
Regarding #define collisions...They really are a pain...but there are some pain relievers that may help...

I always strive to encapsulate (or at least isolate) as much as I can. If I am using third party libraries, or even "uncommon" parts of the compiler provider headers, I will often create wrapper classes rather than use them in my code.

Hijacking Lindley example (without knowing if this approach would work in his case), I would likely have the "#include f2c.h" in the implementation (.cpp) of a few select classes that exposed the exact functionallity in a manner which was independant of "f2c".

I could then include the header(s) that I have complete control of throughout my application without having to deal with this issue.

There is a side-benefit to this approach (which often becomes the prime benefit over the life of the code), in that I can much more readily adapt to ewer versions (which may not be 100% compatible) or even to different vendors). In both cases, only my wrapper/adapter classes would be impacted, and I would not have to go into the body of the code.

This scales up very nicely when you end up developing multiple projects that each use different combinations of third party components....

exterminator
July 11th, 2008, 10:37 AM
When order of 2 header files matters, it means that there is some kind of dependency between the headers. Second header needs first to be there. This is kind of a bad thing to impose on the user. I am of the belief that header files should be self sufficient in that they should include other headers that they need.

I am finding it pretty hard to recall if I ever had to remember the order of includes. Probably, never. Except for the stdafx.h that Graham mentioned.