A C program is made from a collection of translation units
that contain definitions that constitute the behaviour
and state of the program. Each translation unit can be
generated from a source file that undergoes several
translation
phases, an early one of which is
preprocessing. A C preprocessor goes
through a source file line by line, looking for
preprocessing directives, lines that begin with a
hash #
(U+0023). These
directives can have several effects:
-
Some lines can be conditionally ignored, so they take no further part in translation. This conditional compilation allows the program to adapt to the environment which it is being translated for.
-
A directive can instruct the preprocessor to transclude the contents of another file (or some other abstract container of text) in place of the directive. Such header files or headers can contain declarations that must be shared between distinct translation units to ensure compatibility with each other. Without a lot of typing and manual checking, this would be impossible, as each translation unit is translated separately from all others, with no declarations known in one translation being retained to perform another. The process is more usually known as file inclusion.
-
Some directives manipulate a population of macro definitions. When the name of a macro is encountered later in the text of the program (in all lines, not just the directives), it is replaced by the macro's defined expansion. This allows code to be generated from templates, and the expansions can influence the directives that govern conditional compilation. A set of macros predefined by the translation environment especially allow a program to adapt to that environment.
-
Tools exist to generate C source code from other languages. If there's an error in the generated code, it sometimes helps to know where in the original source the error originates. The
#line
directive allows diagnostics about the C code to report the line number in the original file.
- preprocessing-file
groupopt
- group
group-part
group group-part
- group-part
if-section
control-line
text-line
# non-directive
- if-section
if-group elif-groupsopt else-groupopt else-line
- if-group
# if constant-expression new-line group
# ifdef identifier new-line group
# ifndef identifier new-line group
- elif-groups
elif-group
elif-groups elif-group
- elif-group
# elif constant-expression new-line group
- else-group
# else new-line groupopt
- else-line
# endif new-line
- control-line
# include pp-tokens new-line
# define identifier replacement-listopt new-line
# define ident-lparen identifier-listopt ) replacement-list new-line
-
# define ident-lparen ... ) replacement-list new-line
since C99 -
# define ident-lparen identifier-list , ... ) replacement-list new-line
since C99 # undef identifier new-line
# line pp-tokens new-line
# error pp-tokensopt new-line
# pragma pp-tokensopt new-line
# new-line
- ident-lparen
-
identifier (
without intervening white space - identifier-list
identifier
identifier-list , identifier
- text-line
pp-tokensopt new-line
- non-directive
pp-tokens new-line
- replacement-list
pp-tokensopt
- pp-tokens
preprocessing-token
pp-tokens preprocessing-token
- new-line
-
the new-line character