just a beginner question, what's going on with #ifndef SOME_HEADER_H
understandable that it is a preprocessor directive for conditional compilation, if some header is already included (i might be wrong correct me?) move on , if it's not, include
it, i read at some blog the letter sentence with these words instead, if it's defined move on else #define
it, well i thought we can just include a header file not define a header file , how can a header file be defined, and what's the relation here ? and the second question, the file name was foo.h
and when he try to check if it's defined he does #ifndef FOO_H #define FOO_H
, ok how foo.h
have been translated to FOO_H
, does the c mechanism know that he's talking about that specific file or does he done something before-word? thank's for your time!

- 63
- 7
-
Very roughly `#include` is insertion, and macros are search-and-replace. – Some programmer dude Jul 13 '21 at 08:22
-
clear, how a header file can be treated as a macro? – Question Jul 13 '21 at 08:24
-
Because it is *easier* to place the header guard test in the header itself. Not only does the coder of the including file not have to worry about remembering to do it conditionally, they don't have to look up the exact name of the identifier. – Weather Vane Jul 13 '21 at 08:24
-
And for your second question (please, one question per question) then that's a normal [header include guard](https://en.wikipedia.org/wiki/Include_guard). There's no relation between the header file name and the macro being defined. You could define a macro name `FOOBAR` for a header file name `hoppla.h`. – Some programmer dude Jul 13 '21 at 08:24
-
A header is not treated as a macro. The header defines a macro when first included and checks for existancs of the macro when included again. The fact that the macro name and the name of the header are similar is just because you chose it to be similar. – Gerhardh Jul 13 '21 at 08:27
-
Does this answer your question? [C++ #include guards](https://stackoverflow.com/questions/8020113/c-include-guards) – gstukelj Jul 13 '21 at 08:30
2 Answers
There is no such thing as translating foo.h
as FOO_H
, nor such thing as "defining that a .h has already been included". Using preprocessor variables is just the standard way C developers ensure that .h are not included twice.
In C preprocessor, you can use things such as #if
, #else
and #endif
in order to make logic. You can also #define
variables, to store information. You can also use the function defined(...)
to check if a C-preprocessor variable is already defined. The #ifdef MY_VARIABLE
directive is just a shorthand for #if defined(MY_VARIABLE)
, and #ifndef
is just the opposite of that.
On the other hand, you don't want a .h to be included twice, there are several ways to do this, but the standard way is:
/* Check if my variable has already been declared */
#ifndef MY_aWeSoMe_VARIBLE
/* If we are in here, it mean that it is not */
/* So let's declare it */
#define MY_aWeSoMe_VARIBLE
/* You can write some more code here, like your .h stuff */
/* And of course, it's time to close the if */
#endif /* This closes the MY_aWeSoMe_VARIABLE ifndef */
The 1st time your complier will include the .h
, MY_aWeSoMe_VARIABLE
won't be defined yet, so preprocessor will get inside the if
, define the variable, include all the .h
's code. If your compiler comes to include the .h
a 2nd or more time, the variable will already be defined, so the preprocessor won't get inside the if
. Since all the .h
's content is inside the if
, it won't do anything.
Since naming a variable MY_aWeSoMe_VARIABLE
is pretty stupid, people tend to name it like MY_FILE_NAME
, or MY_FILE_NAME_H
, but this is not mandatory, practices actually vary from one dev to another.

- 72
- 1
- 13
What you have here is a header guard:
File: some_header.h
#ifndef SOME_HEADER_H // if SOME_HEADER_H is not defined, enter the
// #ifndef ... #endif block
#define SOME_HEADER_H // and define SOME_HEADER_H
struct foo {
int x;
};
#endif
This protects the header from being included more than once in the same translation unit and thereby trying to define the same entities more than once. The macro SOME_HEADER_H
will stay defined until the translation unit is done so no matter how many times this header is included in the translation unit (implicitly via other header files) its contents will only be parsed once for that translation unit.
You can now do this:
File: some_other_header.h
#ifndef SOME_OTHER_HEADER_H
#define SOME_OTHER_HEADER_H
#include "some_header.h" // this header uses some_header.h
struct bar {
struct foo x;
};
#endif
And a program can now include both header files without getting an error like redefinition of 'foo'
.
File: main.cpp
#include "some_header.h"
#include "some_other_header.h"
int main() {}
A non-standard but quite popular alternative to the classic header guards shown above is #pragma once
which does the same thing (if your preprocessor supports it):
File: some_header.h
#pragma once
// no need for a named macro or #endif
struct foo { ... };

- 93,841
- 5
- 60
- 108
-
if i can see, for a foo.h the header guard is written the in the foo.h it self . so when we call it in other files, we make sure it's not included more than once ? – Question Jul 13 '21 at 08:27
-
@Question The header guard in the header file itself yes. I added a little example – Ted Lyngmo Jul 13 '21 at 08:30