Behaviour of the #ifndef directive is the same in both C and C++.
Purpose
The #ifndef directive is one of five preprocessor selection statements allowing selection of alternative sections of code for compilation. The other four selection statements are: #ifdef, #if, #elif, and #else.
Format
#ifndef macro name
valid preprocessor or code statements
#endif or #elif or #else
All preprocessor directives begin with the # symbol. It must be the first character on the line or the first character on the line following optional white space.
Some early compilers flagged an error if # was not the first character on the line.
Spaces or tabs are permitted between the # and ifndef, but not escape characters or other symbols or macros. The preprocessor removes white space and concatenates the # and ifndef together.
The following are valid uses:
#ifndef my_macro # ifndef my_macro; # ifndef my_macro # /* comments are white space */ ifndef my_macro
The following are invalid uses:
// #\ is not a valid preprocessor directive # \t ifndef my_macro // #" is not a valid preprocessor directive # "" ifndef my_macro
Use
If the macro name does not exist, then the statements following #ifndef until the end of the block (#endif, #else or #elif) are compiled.
If the macro name exists, then the statements following #ifndef until the end of the block (#endif, #else or #elif) are skipped (not compiled).
Since the code is conditionally compiled, it is possible the code never gets compiled and, as a consequence, any errors in it are never caught or noticed.
The simplest preprocessor selection block consists of just an #ifndef and a terminating #endif statement.
More complex selection blocks consist of an #ifndef followed by one or more #elif and / or a final #else statement.
Any valid preprocessor statements, including other #ifndef statements, may be part of the code in the selection block. There is no limit on the level of nesting of selection statements.
The following:
#ifndef my_macro
is equivalent to:
#if !defined my_macro
This directive is most commonly used to prevent multiple inclusion of header files:
#ifndef my_header #define my_header . . . // contents of the header file . . . #endif