0% found this document useful (0 votes)
19 views8 pages

The Preprocessor

The preprocessor is a program that processes source code before compilation. It handles include files, macros, and conditional compilation. Include files allow including external code, macros define constants and functions, and conditional compilation includes/excludes code based on conditions. Proper use of header files and directives like #ifndef prevents errors from multiple inclusions of the same header file.

Uploaded by

Jayant Asudhani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views8 pages

The Preprocessor

The preprocessor is a program that processes source code before compilation. It handles include files, macros, and conditional compilation. Include files allow including external code, macros define constants and functions, and conditional compilation includes/excludes code based on conditions. Proper use of header files and directives like #ifndef prevents errors from multiple inclusions of the same header file.

Uploaded by

Jayant Asudhani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

The Preprocessor 1

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 ‘#’

Pre pr o cessor D i r ecti ves


The first question is: how do we give instructions to the preprocessor? This is achieved by the use
of so-called directives. Directives can be recognised by the presence of the character '#' as the first
character of a line in the source code. The syntax of the preprocessor is independent of the rest of
the language.

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 policy is as follows:

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))

M a c r o D e f i nitio ns an d S u b stit uti o n s


The preprocessor allows the programmer to define constants and macros. When the macro is used
later in the program, it will be replaced by the macro definition by the preprocessor.

The syntax is:


#define <identifier> <token_string>

For example, we can define a constant as follows:

#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:

#define <ident>(<ident>,...,<ident>) <token_string>

For example, we could define a function which calculates the square of its argument. The syntax is:

#define sqr(x) ((x)*(x))

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>

// Some preprocessor directives here


#define PI 3.1415
#define MAX 256
#define sqr(x) ((x) * (x))

main()
{
int upperbound = MAX - 1;
int two = 2;

printf("The value of pi is: %f\n", PI);


printf("Upperbound is: %d\n", upperbound);
printf("The square of 2 is: %f\n", sqr(2.0));

// Some erroneous ways of using the ‘sqr’ macro (for example,


// squaring a character produces a result!)
printf("Square of 3? %d\n", sqr(++two));
printf("Square of character a is :%d\n", sqr('a'));

exit(0);
}
The Preprocessor 7

Conditional Compilation
l #ifdef
l #ifndef
l #elif
l #else
l #endif

C o n d iti o nal C o m p ilatio n


When working with large C systems it is necessary to compile functions. However, sometimes
compilation should occur only under certain conditions. For example, we can take differences
between various compilers and platforms into account and whether a certain file has already been
included in a certain source file.

An example on how conditional compilation can be implemented is shown below.


For example, different compilers use different names for certain commonly used files. In this case
we can define so-called environment variables to let us choose the right file depending on the
current compiler.

#include <stdio.h>
#include <string.h>
#include <ctype.h>

/* Using the preprocessor to handle different compilers */


#ifdef __XWINDOWS__ /* X windows io*/
#include <xwinio.h>
#elif __WINDOWS /* Windows io */
#include <winio.h>
#else /* DOS io */
#include <stdio.h>
#endif

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

Header Files and Directives


l Can include header file multiple times
l This can lead to redefinition errors
l Prevent multiple inclusion:
#ifndef CONSTANT_NAME
#define CONSTANT_NAME

/* declarations */

#endif

H e a d er Files a n d D irecti ves


When creating your own header files we have to make sure that that our definitions are declared
only once.

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.

You might also like