does the order of the #include directives matter? if so, why and how do you know what the order is?
Printable View
does the order of the #include directives matter? if so, why and how do you know what the order is?
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.
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.
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...
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:
because that's the only way I could get it to play nicely with stdlib.h.Code:#include "f2c.h"
#undef abs
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.
And what about using different names in your library, or ditch/minimize #defines and use namespaces instead.Quote:
Originally Posted by Lindley
Good advice in general. Just for the record, though, f2c isn't mine. It's a common Fortran-to-C interface.
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.Quote:
Originally Posted by STLDude
I hate those two stupid evil macros. HATE HATE HATEQuote:
#define min and #define max
It gets better ...
Have fun figuring out the compiler errors if you try to declare a function with one of those names in your class.Quote:
Originally Posted by WinBase.h
:eek:
HATE HATE HATE
sorry for the spam, but I really do hate
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.
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....
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.