
The Preprocessor
The preprocessor is a tool that precedes the compiler in interpreting the code. The #include
directive is one of its parts. It opens the file and includes its text. So far, we have only included system header files, whose names are surrounded by arrow brackets (<
and >
). Later on, we will include our own header files. Then we will use parentheses instead of arrow brackets. The difference is that the preprocessor looks for the system header files in a special system file directory while it looks for our header files in the local file directory.
Another part of the preprocessor is the macros. There are two kinds: with or without parameters. A macro without parameters works like a constant.
#define ARRAY_SIZE 256 int arr[ARRAY_SIZE];
The predefined macros __DATE__, __TIME__, __FILE__ , and __LINE__ holds today's date, the current time, the current line number, and the name of the file, respectively.
Macros with parameters act like functions with the difference being that they do not perform any type checking, they just replace the text. A macro is introduced with the #define
directive and is often written with capitals.
#define ADD(a, b) ((a) + (b)) cout << ADD(1 + 2, 3 * 4) << endl; // 15
One useful macro is assert
, it is defined in the header file cassert
. It takes a logical parameter and exits the program execution with an appropriate message if the parameter is false. exit
is a standard function that aborts the execution of the program and returns an integer value to the operating system. When a macro definition stretches over several lines, each line except the last one must end witha backslash.
#define assert(test) \ { \ if (!(test)) \ { \ cout << "Assertion: \"" << #test << "\" on line " \ << __LINE__ << " in file " << __FILE__ << "."; \ ::exit(-1); \ } \ }
In the error handling section of the next chapter, we will define an error checking macro displaying the error message in a message box.
It is also possible to perform conditional programming by checking the value of macros. In the following example, we define a system integer according to the underlying operating system.
#ifdef WINDOWS #define SYSINT int #endif #ifdef LINUX #define SYSINT unsigned int #endif #ifdef MACHINTOCH #define SYSINT long int #endif SYSINT iOpData = 0;