Why do you need inclusion guard for C++ header files?

  • A+

I get roughly what it does. What I don't understand is why it's not the default? What are the use cases where some header file would need to be included multiple times?


The reason it's not the default is primary historical these days -- when the C language was formalized, #include was specified that it must act exactly as if the user had copy-and-pasted the specified file's contents at the location of the #include-line; and C++ wanted (and wants) to remain as compatible as possible with C, so C++ inherited that behavior from C.

As for a use-case where including the same header file more than once might be useful; one time where I found it useful was for simulating a templated-container-class in C (because C doesn't support templates directly). I had a container-implementation-header-file that looked something like this (but more elaborate; I'm showing a simplified version here for readability):

// MyContainerImplemention.h // be sure to #define MYTYPE and MYARRAYSIZE // before #include-ing this file!  struct ArrayOf##MYTYPE {    MYTYPE arrayOfItems[MYARRAYSIZE]; };  inline void Set##MYTYPE##Item(struct ArrayOf##MyType * container, int which, MYTYPE item)  {    container[which] = item; }  [... and so on for various other MYTYPE-specific methods ...] 

... then my .c files could do something like:

#define MYTYPE int #define MYARRAYSIZE 10 #include "MyContainerImplementation.h" #undef MYARRAYSIZE #undef MYTYPE  #define MYTYPE short #define MYARRAYSIZE 15 #include "MyContainerImplementation.h" #undef MYARRAYSIZE #undef MYTYPE  struct ArrayOfint myInts; struct ArrayOfshort myShorts;  SetintItem(&myInts, 5, 12); SetshortItem(&myShorts, 3, 2); [...] 

... and end up with the container "class" and its associated methods implemented for each data-type, without having to manually write a new implementation of the container "class" each time.

Yes, it was extremely ugly -- but not as ugly as having to manually write out thousands of lines of redundant container-code would have been. (The real container-implementation-header-file implemented a hash table and was several hundred lines long)


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: