The C standard defines 8 translation phases. A source file is processed by each of the 8 phases in sequence (or in an equivalent manner).
Phase 4, as defined in N1570 section 5.1.1.2, is:
Preprocessing directives are executed, macro invocations are expanded, and
_Pragma
unary operator expressions are executed. If a character sequence that matches the syntax of a universal character name is produced by token concatenation (6.10.3.3), the behavior is undefined. A#include
preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted.
The relevant sentence here is:
A
#include
preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively.
which implies that each included source file is preprocessed by itself. This precludes having a #if
in one file and the corresponding #endif
in another.
(As "A wild elephant" mentioned in comments, and as rodrigo's answer says, the grammar in section 6.10 also says that an if-section, which starts with a #if
(or #ifdef
or #ifndef
) line and ends with a #endif
line, can only appear as part of a preprocessing-file.)