All preprocessor commands begins with the hash (pound) symbol #
.
A C macro is just a preprocessor command that is defined using the #define
preprocessor directive. During the preprocessing stage, the C preprocessor (a part of the C compiler) simply substitutes the body of the macro wherever its name appears.
When a compiler encounters a macro in the code, it performs simple string replacement, no additional operations are performed. Because of this, changes by the preprocessor do not respect scope of C programs - for example, a macro definition is not limited to being within a block, so is unaffected by a '}'
that ends a block statement.
The preprocessor is, by design, not turing complete - there are several types of computation that cannot be done by the preprocessor alone.
Usually compilers have a command line flag (or configuration setting) that allows us to stop compilation after the preprocessing phase and to inspect the result. On POSIX platforms this flag is -E
. So, running gcc with this flag prints the expanded source to stdout:
$ gcc -E cprog.c
Often the preprocessor is implemented as a separate program, which is invoked by the compiler, common name for that program is cpp
. A number of preprocessors emit supporting information, such as information about line numbers - which is used by subsequent phases of compilation to generate debugging information. In the case the preprocessor is based on gcc, the -P option suppresses such information.
$ cpp -P cprog.c