1.9.1. Anatomy of the C header file

Now, let us break and dive deeper into the anatomy of file greeting.h that we used in Use common header file.

greeting.h — Header Guards
1
2
3
4
5
6
#ifndef GREETING_H
#define GREETING_H

void greeting(void);

#endif /* GREETING_H */

In lines 1 and 6, we are guarding the logic of this header file against the definition GREETING_H. If GREETING_H has not been defined yet, then and then only process the code within #if... and #endif. We do not see similar construct in other higher order programming languages, but the way C programming language is defined, this is an important step. Large scale software easily get nested inclusion hierarchy. And because the way C Language preprocessor [1] works, due to nested inclusion by other header files, a given header file may be included multiple times and it would result into an error for multiple declaration of the same item.

greeting.h — Self Define
1
2
3
4
5
6
#ifndef GREETING_H
#define GREETING_H

void greeting(void);

#endif /* GREETING_H */

In line no. 2, GREETING_H is defined. If GREETING_H was already defined, line no. 2 would never get processed. It would be removed from processing between line nos. 1 and 6. On the other hand, if GREETING_H was never defined so far, we define it now, inside this header file itself. And thus the file greeting.h is safe guarded from issues with multiple inclusions.

[1]Explaining in detail how preprocessor works is out of the scope of the book. For more details see https://en.wikipedia.org/wiki/C_preprocessor