The preprocessor, in general, is a program that processes its input and gives output which is then used as an input of some other program. This is called preprocessing, and it is often used in the first stages of code compilation (in many implementations, the preprocessor is invoked by the compiler). There are many different implementations of the preprocessor, and their functions can vary - for example, some preprocessors can only perform simple plain text substitutions, while some are powerful enough to be considered programming languages themselves.
Specifically, in C/C++, the preprocessor is invoked by the compiler and preprocessing is performed as the first stage of translation. C++'s preprocessor has the following capabilities: inclusion of header files, macro expansions, conditional compilation etc.
The preprocessor in C++ is given instructions using preprocessor directives: lines included in the code which are not actual program statements but directives for the preprocessor. All preprocessor directives begin with the # sign, and they only extend across one line of code.
We have already used preprocessor directives - the most common example is including another file in our source file using the
#include directive. For example, if we write
std::cout << "Message";
the preprocessor will process the
directive and copy the content of the included file into our own source file. Sometimes you will see that the filename which we want to include is enclosed within double quotes - in this case, the search path includes the current source directory (normally, the file is searched for in the standard compiler include paths).
Another very common use of preprocessor directives is the
#define directive. This directive enables the programmer to create symbolic constants called macros. The general form of the directive is:
#define macro replacement
When this line appears in a file, all subsequent occurrences of
in that file will be replaced by
before the program is compiled. For example:
#define PI 3.14159
std::cout << PI;
Similarly, it is also possible to write more complex, function-like macros which can help simplify our code:
#define MAX(x, y) (x > y)? x : y
Another interesting feature of the preprocessor are the # and ## operators. The # operator converts a
replacement token to a string surrounded by quotes:
#define TO_STRING(x) #x
cout << TO_STRING(Message); //output: Message
and the ## operator is used to concatenate two tokens, for example:
#define concat(a, b) a ## b
int xy = 100;
cout << concat(x, y); //output: 100