Include guards are not actually a feature of the language itself, they're just a way to ensure the same header file isn't included twice into the same translation unit, and they're built from lower-level language features.
The actual features that make this possible are macro replacement (specifically object-like macros) and conditional inclusion.
Hence, to find out where the FILE_H
comes from, you need to examine two things.
The first is the limitations imposed by the standard (C11 6.4.2
for example). In macro replacement, the macro name must be drawn from a limited character set, the minimum of which includes the upper and lower case letters, the underscore, and the digits (there are all sorts of extras that can be allowed, such as universal character names or other implementation-defined characters but this is the mandated baseline).
The second is the mind of the developer. Beyond the constraints of the standard, the developer must provide a unique identifier used for the include guard and the easiest way to do this is to make it reliant somehow on the file name itself. Hence, one practice is to use the uppercase file name with .
replaced by an underscore.
That's why you'll end up with an include guard for btree.h
being of the form:
#ifndef BTREE_H
#define BTREE_H
// weave your magic here
#endif
You should keep in mind however that it doesn't always work out well. Sometimes you may end up with two similarly named header files that use the same include guard name, resulting in one of the header files not being included at all. This happens infrequently enough that it's usually not worth being concerned about.