49

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?

Community
  • 1
  • 1
math4tots
  • 8,540
  • 14
  • 58
  • 95
  • 13
    Yes, it **should** be the default behaviour, because it is the common case *(they could have defined a new preprocessor-directive `#multipleincludes` or something, for the rare case that you want multiple-inclusion)*. But C was designed to make a compiler easy to write from scratch, not easy to program for. This made sense in the 1970's, when there were many common architectures, no easily modifiable open-source compilers like `gcc`, and programs rarely went over 100k lines. It doesn't make sense for 2012. **Always make the common case the default!** – BlueRaja - Danny Pflughoeft Jun 04 '12 at 17:14
  • I think it's **not a duplicate**: it doesn't question the purpose of the technical solutions but for the actual purpose of #include. *This* is a question that I just wanted to ask, whereas the other is not. – Wolf Dec 14 '17 at 11:15
  • I was evaluating the reopen votes and decided to keep it closed. Even if it is not a dupe the question seems to be speculative in nature and likely to attract opinion-based answers - which is also off-topic for this site. – Paulo Scardine Dec 14 '17 at 14:48

6 Answers6

30

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.

Pubby
  • 51,882
  • 13
  • 139
  • 180
28

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 of NDEBUG 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.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
14

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>";
}
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • In C, trailing commas in enumerator lists are allowed (for exactly this case). Is this really different in C++? – undur_gongor Jun 04 '12 at 09:28
  • @undur_gongor: dug around a bit - seems it's not allowed in C++03 and earlier, but tolerance is added in C++11. Of course specific compilers may have been more tolerant even under C++03. – Tony Delroy Jun 04 '12 at 11:30
5

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.

ThomasCle
  • 6,792
  • 7
  • 41
  • 81
  • 13
    /me never understood why people would choose a non-portable solution, when some `ifdef`'s aren't much harder. – Benjamin Bannier Jun 04 '12 at 07:07
  • 2
    In **C++** you use header guards. In nonportable C++, you use #pragma once – jalf Jun 04 '12 at 07:09
  • Thanks for correcting it honk. I've now edited my answer. – ThomasCle Jun 04 '12 at 07:10
  • 4
    /me also never understood the compulsive use of starting underscores in include guards ;) – Benjamin Bannier Jun 04 '12 at 07:10
  • 5
    Underscore capital is reserved. Just start with the name of your project. – Pubby Jun 04 '12 at 07:13
  • Seems like a bad copy/paste from an old example. Done :) Again thanks. – ThomasCle Jun 04 '12 at 07:13
  • 2
    @honk: using `#pragma once` can be more effective than **header guards**, And pragma once being non portable doesn't hurt at all because if it is not supported by the compiler then standard mandates that the compiler should just ignore it. – Alok Save Jun 04 '12 at 07:24
  • 3
    @Als: I know it is supported by newer MSVC, GCC and clang compilers, but it still isn't standard C++ and include guards aren't much harder. As for `#pragma once` being more effective, I would be curious to see some comparison, since at least GCC and clang recognize include guards and treat them pretty similar to the `#pragma`. – Benjamin Bannier Jun 04 '12 at 07:29
  • 2
    @Als: but it's possible for the compiler to recognize it and do something unexpected (e.g., really old versions of gcc "recognized" *all* pragmas -- but *most* had effects many would consider undesirable). – Jerry Coffin Jun 04 '12 at 07:29
  • 2
    @JerryCoffin: As I understand, In that case it is merely a particular compiler bug if it says something and does something else, just as any other compiler bug.It should not be deemed as portability issue against prama once? – Alok Save Jun 04 '12 at 07:32
  • @Als: At least according to the standard, no, not really. The standard places no limits on the degree to which you might consider the behavior unrelated to what you thought you said. It just says it causes implementation defined behavior, and specifically includes acting in an otherwise non-conforming manner as a possibility. – Jerry Coffin Jun 04 '12 at 15:24
  • People use `#pragma once` because it's less boilerplate and is guaranteed to affect the entire file. – Inverse Jun 04 '12 at 16:51
  • @honk: using `#ifdef`s is indeed _sometimes_ harder. For example, if you are writing a library, and the library has internally `tools.h`, and the include guard is by just customary `#define TOOLS_H`, you are calling for problems if your library's client is using the same header file name in the project. `#pragma once` is free from this issue, too bad it didn't make into standard. – Vlad Jun 07 '12 at 19:04
1

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
-6
#ifndef _INC_HEADER_
#define _INC_HEADER_

//header code

#endif

Where HEADER is the header's name

eg. main_win.h will be _INC_MAIN_WIN_

lazy_banana
  • 450
  • 5
  • 10