The Preprocessor
The Preprocessor
The Preprocessor
This material is intended for students of the “C++ Programming for Financial Engineering” certificate
A joint project by the Baruch MFE program, Datasim Education BV and Quant Network LLC
© Datasim Education BV 2011. Unauthorized distribution is prohibited.
2 The Preprocessor
Overview
l Include files
l Macros
l Conditional compilation
O b j ecti ves
Topics discussed in this unit:
· Include files
· Macros
· Conditional compilation
Introduction
The C preprocessor is based on the ANSI C processor and is not considered to be part of
the C compiler as such. Its functions are:
- Macro definition and substitution.
- Conditional compilation.
- Source file inclusion.
The preprocessor has other capabilities but these are not discussed here.
The Preprocessor 3
Introduction to Directives
l Preprocessor directives start with ‘#’ e.g.:
#include
#define
l Preprocessor looks for ‘#’
We advise on using the preprocessor as little as possible. Much of the functionality can be achieved
by C itself. In many cases however, the preprocessor must be used.
This material is intended for students of the “C++ Programming for Financial Engineering” certificate
A joint project by the Baruch MFE program, Datasim Education BV and Quant Network LLC
© Datasim Education BV 2011. Unauthorized distribution is prohibited.
4 The Preprocessor
Include Files
l Common definitions in header file
l Include header file when needed
l For system header files
#include <stdio.h>
l For own header files
#include "mine.h"
F ile I n cl usi o n
It is possible to let the preprocessor include certain files into the current file. This is done by the
"include" directive. The syntax of the include directive is:
#include <filename.h>
The include directive causes the line beginning with ‘#’ to be replaced by the entire contents of the
file whose name is between the brackets <>.
The directive:
#include <filename>
causes the preprocessor to search for a file in a defined sequence of standard places (the include
directory).
The directive:
#include "filename"
causes the file to be searched first in the directory of the original source file. The include directive
can be used to handle compiler dependencies.
The Preprocessor 5
Macros
l For global magic numbers
#define MAX 256
l Macros with arguments (not a function)
#define sqr(x) ((x) * (x))
#define PI 3.14159
Anywhere in future code where PI is referred, it will be replaced by the value from the macro
definition (in this case 3.14159).
It is also possible to define more complicated expressions for the preprocessor. In general, the
syntax takes the form:
For example, we could define a function which calculates the square of its argument. The syntax is:
The main disadvantages of using the #define directive are first that type checking is weak (what is
there to stop us calculating sqr(‘a’) ?) and secondly, it is less rigorous than the compiler.
An example of how problems can arise with the preprocessor is now given. It shows how useful the
preprocessor is but it also shows a number of pitfalls.
This material is intended for students of the “C++ Programming for Financial Engineering” certificate
A joint project by the Baruch MFE program, Datasim Education BV and Quant Network LLC
© Datasim Education BV 2011. Unauthorized distribution is prohibited.
6 The Preprocessor
/*
Program to show how the preprocessor works.
(C) Datasim BV 1995
*/
#include <stdio.h>
#include <stdlib.h>
main()
{
int upperbound = MAX - 1;
int two = 2;
exit(0);
}
The Preprocessor 7
Conditional Compilation
l #ifdef
l #ifndef
l #elif
l #else
l #endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
This material is intended for students of the “C++ Programming for Financial Engineering” certificate
A joint project by the Baruch MFE program, Datasim Education BV and Quant Network LLC
© Datasim Education BV 2011. Unauthorized distribution is prohibited.
8 The Preprocessor
/* declarations */
#endif
There is a possibility that a header file gets included more than once during one compilation. The
definitions in that header file will be defined more than once and generate a compiler error.
#include "mine.h"
#include "mine.h" /* Error multiple declarations */
To prevent this from happening we can use conditional compilation to make sure the definitions in
that header file are declared once each compile operation. We define a constant for each header file.
Before giving our definitions in the header file we check to see if that constant is defined. If the
constant is not defined we define it along with the rest of the definitions. We do this by using the
#ifndef and the #endif directive. Everything between these two directives is part of the if
construction.
#ifndef MINE_H
#define MINE_H
void print(void);
/* Other definitions */
#endif
The first time the header file is included the global constant MINE_H is not defined and the #ifndef
directive evaluates to true. The #define directive defines the global constant MINE_H. Following
this definition we place the definitions we would have placed in the header file followed by a
#endif. The second time the header file is included in one compilation the MINE_H constant is
already defined and the definitions between the #ifndef and #endif are skipped.