I've used some very large scale systems and never seen a required order, but came across it recently. Does the STL or STD library or even Boost have any cases where certain includes must come in a certain order?
Does the STL or STD library or even Boost have any cases where certain includes must come in a certain order?
For the standard, the answer is emphatically, no. I imagine the same is true for Boost, though I haven't looked it up.
From the C standard:
Standard headers may be included in any order; each may be included more than once in a given scope, with no effect different from being included only once, except that the effect of including
<assert.h>
depends on the definition ofNDEBUG
(see 7.2).
the C++ standard has similar wording.
My preference is that headers should include their own dependencies, but I've worked with people who believe this to be 'wasteful'. In my opinion, not having headers include their dependencies is a worthless early optimization.
This definitely sounds like a bad design. If somehow a specific order was required, the library should provide one header that includes the other ones in the correct order.
As far as boost, and the STL, I'm pretty sure I haven't encountered this situation yet.
Needing to specify includes in a specific order almost always indicated a design problem. One way to reduce the possibility of inadvertantly doing this, is to get into the practice of including a class's header file as the first #include in the implementation file.
// A.cpp
#include "A.h"
#include "boost/shared_ptr.hpp"
#include <vector>
class A {
// ...
};
This way if, for example, A.h uses a vector without the right #include, A.cpp won't compile.
I can't remember where I picked this up; it might have been from "Large Scale C++ Design" by Lakos (a great book that could really use an update).
Does the STL or STD library or even Boost have any cases where certain includes must come in a certain order?
I have never come across this and if it is so then the authors must be notified ASAP. And oh yes its a very bad design.
That is a 'bad thing'. A better way has been mentioned; but I'll elaborate.
//a.h #ifndef _A_H_ #define _A_H_ //... code ... #endif // ----------------- //b.h #ifndef _B_H_ #define _B_H_ #include a.h //... code ... #endif // ----------------- //main.cpp Try 1 #include "b.h" //<- okay! b includes a, then does b // ----------------- //main.cpp Try 2 #include "a.h" //<- includes a #include "b.h" //<- okay! b includes a, but skips redefining it, then does b // ----------------- //main.cpp Try 3 #include "b.h" //<- b includes a, then does b #include "a.h" //<- okay! a skips redefining itself! // ----------------- //main.cpp Try 4 #include "a.h" //<- fail! b is not included anywhere =(
It's a common technique to include a project level compatibility header (say compat.h) as the first header of any .c/.cpp source files, which defines a bunch of required macros like __STDC_LIMIT_MACROS, __REENTRANT and other project wide macros to affect the subsequent behavior of standard headers.
I first saw this usage long time ago by a competent programmer for an internal library. Later I saw 'git' (the infamous dvcs) project use this technique as well.
If the functions and/or classes contained in header (say, A.h) depend on functions and/or classes defined in another header (say, B.h), I prefer to include the latter in the first, rather to force the users of the first one to include both in a particular order.
Yes:
// A.h
#pragma once
// or the #ifndef trick
#include "B.h"
// A.cpp
#include "A.h"
No:
// A.h
#pragma once
// or the #ifndef trick
//#include "B.h"
// A.cpp
#include "B.h"
#include "A.h"
I like including headers in alphabetical order - makes it easy to see what I've already done.
If a lib won't work because it's in the wrong order, then it's broken and should be fixed so as to be order-independent.
To me it is a bad design that, unluckily, happens to be in win32 API with socket/socket2 includes, if I recall correctly. The result is that an error in inclusion order will trigger a set of errors that just happen to come from nowhere and may be hard to debug in the cases where the dependency changes the definitions but the code still compiles.
In any other case, you will still run into trouble. If you don't include header x.h because y.h already includes it, then your code is dependent on y.h dependency on x.h. If at a later time y.h is refactored and it no longer requires y.h, the removal of the include will break your code base. This is a sign of coupling (even if not at the class level): changes in one part of the code base need to propagate and extend to other parts of code.
It's perhaps a sign that you're using MFC, which might in turn indicate bad design (joke... or is it?)
(At least, the last time I looked at MFC, it was really picky about where you included <windows.h>
)
Not to my knowledge. It's pretty bad practice. I've run into it recently with a Windows header and some weird interface in my code, though.
You should be using include guards and forward declarations, in that way you shouldn't have much problems with the order of including headers.
Sometimes it's still required that a header is included first or last, no idea why.
(For example: In the Source SDK)
Yes, requiring a certain order for includes in c++ is a sign of bad library/header design.
Though forward declarations may require more than one file to be included in order to fully use a class. See example below:
// A.h
class B; // forward declaration
class A
{
void doStuff(const B& b);
};
// main.cpp
#include <A.h>
#include <B.h>
int main()
{
A a;
B b;
a.doStuff(b);
}
© 2022 - 2024 — McMap. All rights reserved.