Including header files in C/C++ more than once [duplicate]
Yes, it's useful when generating code with the preprocessor, or doing tricks like Boost.PP does.
For an example, see X Macros. The basic idea is that the file contains the body of the macro and you #define
the arguments and then #include
it. Here's a contrived example:
macro.xpp
std::cout << MESSAGE;#undef MESSAGE
file.cpp:
int main() {# define MESSAGE "hello world"# include "macro.xpp"}
This also allows you to use #if
and friends on the arguments, something that normal macros can't do.
Yes, including a header more than once can be useful (though it is fairly unusual). The canonical example is <assert.h>
, which defines asssert
differently depending on whether NDEBUG
is defined or not. As such, it can make sense to include it, then have a (usually conditional) definition of NDEBUG, followed by including it again, with (at least potentially) different definitions of assert
:
The
assert
macro is redefined according to the current state ofNDEBUG
each time that<assert.h>
is included1.
Most headers, however, go to some pains to be idempotent (i.e., to have the same effects no matter how often they're included).
1C99, ยง7.2/1.
A typical example (untested) - point being that it factors a list of enumerations so they appear consistently in an enum
and in streaming code:
// states.hX(Uninitialised)X(Initialised)X(Running)X(Complete)X(Shutdown)// app.c++#if defined(X)# error X is already defined#endifenum States { #define X(TAG) TAG, #include "states.h" #undef X Extra_So_Trailing_Comma_Ignored};std::ostream& operator<<(std::ostream& os, const States& state){ #define X(TAG) if (state == TAG) return os << #TAG; #include "states.h" #undef X return os << "<Invalid-State>";}