6

I know C or C++ code usually needs to use include guards like this:

#ifndef __A__H__
#define __A__H__
class A{
};
#endif

and to speed up compile time, in other cpp (e.g.:B.cpp), it can change

#include "A.h"

to:

#ifndef __A__H__
#include "A.h"
#endif

but the question is why doesn't the compiler automatically add or generate the include guard, and therefore why does the programmer need to add it manually if an include guard is usually required?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ggrr
  • 7,737
  • 5
  • 31
  • 53
  • 2
    It doesn't *need* it, it's just handy in *certain* circumstances. But the main reason it's not generated automatically is because it's not part of the language standard to do so. – paxdiablo Aug 10 '15 at 04:36
  • 2
    Because it is sometimes useful to include the same header more than once. – jxh Aug 10 '15 at 04:37
  • 2
    I want to play the devil's advocate here, let's suppose that the compiler needs to be able to automatically generate guards, can it? would it even be feasible? I'm thinking, how can the compiler determine that a file got already included? what if you have 2 files with same name at different absolute paths, but they are actually same file? – Kam Aug 10 '15 at 04:41
  • 1
    btw you cannot use identifiers started with two underscores – Slava Aug 10 '15 at 04:51
  • possible duplicate of [Including header files in C/C++ more than once](http://stackoverflow.com/questions/10877494/including-header-files-in-c-c-more-than-once) –  Aug 10 '15 at 05:05
  • I doubt very much that the second construct will "speed-up compile time" significantly. Perhaps in the days when when the mass storage media was a floppy disk! You will probably spend more time typing that stuff that it will ever save in build time. – Clifford Aug 10 '15 at 06:56
  • Note that you should not, in general, create function, variable, tag or macro names that start with an underscore. Part of [C11 §7.1.3 Reserved identifiers](https://port70.net/~nsz/c/c11/n1570.html#7.1.3) says: — _All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use._ — _All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces._ The rules in C++ are more stringent — you should not create names that contain a double underscore. – Jonathan Leffler Jul 08 '19 at 06:01

2 Answers2

10

There are times when it is absolutely incorrect to generate the header guard. The standards contain an example: <assert.h> in C and <cassert> in C++.

The effect of reincluding those headers depends on the state of the NDEBUG macro when the header is (re)included. It is legitimate to write:

#undef NDEBUG
#include <assert.h>
…code using assert…
#define NDEBUG 1
#include <assert.h>
…more code using assert…

If the compiler automatically generated a header guard, that would not work correctly. Therefore, compilers do not generate header guards automatically.


Incidentally, user code should not use header guard macro names that start with double underscore, or underscore capital letter. Such names are reserved for the implementation. In C++, no user-defined name may legitimately contain a double underscore at all. Use something more like:

#ifndef A_H_INCLUDED
#define A_H_INCLUDED
…body of header…
#endif
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

The compiler, or more strictly the pre-processor cannot determine the programmer's intent in using inclusion. The compiler does not explicitly distinguish between .h files and .c or .cpp files; they differ only in the type of code one places in them. In fact the compiler deals only in a single translation unit; it is the responsibility of the C preprocessor to concatenate all included files into a single file for compilation. It would be incorrect for the pre-processor to omit an inclusion that it has previously included because it has no semantic knowledge of the code and may cause intended behaviour to change by second-guessing the developer.

In some circumstances, an IDE may add include guards for template code that it has generated. For example Microsoft Visual Studio will add them for code that it generates via its project start-up wizards. If it happens at all, it is properly the responsibility of the IDE rather than the compiler or pre-processor.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Clifford
  • 88,407
  • 13
  • 85
  • 165