Let's say I have a header file "header.h" with a function definition.
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void){
return 2;
}
#endif
This header file has an include guard. However, I'm kind of confused as to what #define HEADER_FILE is actually doing. Let's say I were to forget the include guard, it would have been perfectly legal for me to completely ignore adding '#define HEADER_FILE'.
What exactly are we doing when we define HEADER_FILE? What are we defining? And why is it okay to forget the include guard in which case we can also forgot adding #define HEADER_FILE?
It's a preprocessor macro.
All of it is preprocessor syntax, that basically says, if this macro has not already been defined, define it and include all code between the #ifndef
and #endif
What it accomplishes is preventing the inclusion of file more than once, which can lead to problems in your code.
Your question:
And why is it okay to forget the include guard in which case we can also forgot adding #define HEADER_FILE?
It's OK to forget it because it's still legal C code without it. The preprocessor processes your file before it's compiled and includes the specified code in your final program if there's no logic specifying why it shouldn't. It's simply a common practice, but it's not required.
A simple example might help illustrate how this works:
Your header file, header_file.h
we'll say, contains this:
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void){
return 2;
}
#endif
In another file (foo.c
), you might have:
#include "header_file.h"
void foo() {
int value = two();
printf("foo value=%d\n", value);
}
What this will translate to once it's "preprocessed" and ready for compilation is this:
int two(void){
return 2;
}
void foo() {
int value = two();
printf("foo value=%d\n", value);
}
All the include guard is accomplishing here is determining whether or not the header contents between the #ifndef ...
and #endif
should be pasted in place of the original #include
.
However, since that function is not declared extern
or static
, and is actually implemented in a header file, you'd have a problem if you tried to use it in another source file, since the function definition would not be included.
You prevent the file from being included more than once, here
#ifndef HEADER_FILE
you test if HEADER_FILE
is NOT defined, in case that's true then
#define HEADER_FILE
would define it, now if you include the file in another file, the first time it will define HEADER_FILE
, while the second time, it will be already defined and hence the content of the file is not included again, since the #ifndef HEADER_FILE
will be false.
Remember that these are evaluated by the preprocessor before actual compilation is done, so they are evaluated at compile time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With