Including header files in C/C++ more than once [duplicate]
Is it ever useful to include a header file more than once in C or C++?
If the mechanism is never used, why would the compiler ever worry about including a file twice; if it really were useless, wouldn't it be more convenient if newer compilers made sure every header is included only once?
Edit:
I understand that there are standard ways of doing things like include guards and pragma once, but why should you have to specify even that? Shouldn't it be the default behavior of the compiler to include files only once?
Solution 1:
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.
Solution 2:
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.
Solution 3:
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.h
X(Uninitialised)
X(Initialised)
X(Running)
X(Complete)
X(Shutdown)
// app.c++
#if defined(X)
# error X is already defined
#endif
enum 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>";
}
Solution 4:
Yes it would be more convenient only to include it once and that is why you use #pragma once . in C++ :)
Edit:
Note: #pragma once is non-portable. You can use
#ifndef FILENAME_H
#define FILENAME_H
in top of your header files instead if you want it to be portable.
Solution 5:
Multiple inclusion can be used whenever you need some "boring" code generation that you don't want to maintain by hand, again and again.
The classic example would be a C/C++ enum and the corresponding strings, which more or less looks like this:
// MYENUM_VALUES.H
MYENUMVALUE(a)
MYENUMVALUE(b)
MYENUMVALUE(c)
MYENUMVALUE(d)
// MYENUM.H
#define MYENUMVALUE(x) x,
enum MyEnum
{
#include "MYENUM_VALUES.H"
}
#undef MYENUMVALUE
// MYENUMTOSTRING.C
#define MYENUMVALUE(x) case x : return #x;
const char * MyEnumToString(MyEnum val)
{
switch (val)
{
#include "MYENUM_VALUES.H"
default return "unknown";
}
}
#undef MYENUMVALUE