Preprocessor Directives
The preprocessor is part of your compiler and when you compile a program the preprocessor is the first person to scan through your coding. It is particularly bothered with some specific instructions that are meant exclusively for it. These instructions are known as preprocessor directives and the preprocessor searches your program for them. How does it know that some code is meant for it? Preprocessor directives start with the # (hash) symbol and also they need not be terminated by a semi-colon. You have different types of preprocessor directives:
#include:
You’ve already been using this in all of your C++ coding. It simply includes the contents of whatever you include into the source file. One favourite C++ question is: What’s the difference between
#include "iostream.h"
#include <iostream.h>
The only difference is in the way the compiler searches for the iostream.h file. If you use the double quotes, the compiler will start searching for the header file in the directory where you have your source file. If it doesn’t find it here, it will then search in the directory where the compiler is supposed to search for header files.
If you use the angle brackets, the compiler will search in the directory supposed to be having all header files. You usually have an option in your C++ compiler where you can change the default directory used by the compiler (of course don’t change it unless you have specifically made a new directory with the header files).
#define: We’ve seen about this in the section on constants. This used to be the method for C programmers to create constants. Constants created using #define are also called as "macros". It is not only used to create constants but can also be used for defining functions. It is equivalent to the inline function option available in C++. Of course in C++ it is not advisable to use #define because you can make use of the inline keyword and also the const keyword.
#undef: This is the opposite of #define. It will undefine anything that you defined earlier. For example:
#define speed 100
#undef speed
#define speed 200
#if….#elif…..#else…..#endif : This is equal to our if….else if….else statement construct. Endif is used at the end to indicate the end of the ‘if’ block.
#include <iostream>
using namespace std;
#define speed 200
int main( )
{
#if speed= =200
cout<<"Speed is 200";
#elif speed = =100
cout<<"Speed is 100";
#else
cout<<"I don't know what's the speed!";
#endif
return 0;
}
The output is:
Speed is 200
#elif is actually a shortened expression for else if. Instead of mentioning the directives inside the main ( ) function you could use them for defining the value of some other value outside the main ( ) function.
#include <iostream>
using namespace std;
#define speed 200
#if speed= =200
#define brake 100
#elif speed= =100
#define brake 50
#else
#define brake 25
#endif
int main( )
{
cout<<brake;
return 0;
}
#ifdef…..#ifndef:
#ifdef means if the particular variable is defined do something.
#ifndef means if the particular variable is not defined do something.
The syntax is:
# ifdef variable-name
//body
#endif
This can also be written as:
# if defined (variable-name)
//body
#endif
Check out a short program given below:
#include <iostream>
using namespace std;
#define speed 200
int main( )
{
#ifdef speed
cout<<"Speed Defined";
#else
cout<<"Speed not defined";
#endif
#ifndef brake
cout<<endl<<"Brake not defined";
#endif
return 0;
}
Output is:
Speed Define
Brake not defined
As can be seen above, the variable ‘brake’ is not defined in the program. Usually #ifndef and #endif are used in multiple file programs. This is explained later in the chapter.
#line:
All your programs have a certain number of lines (depending on the size of your coding). When you get errors, the compiler will inform you about the line number, which has an error. Using the
#line line-number
you can change the starting line number that is used by the compiler for the program. This might not seem very useful to you but anyway it’s better to know about the various directives that exist.
#pragma:
This is used to make changes in your compiler settings. The use of this directive is compiler-dependent since each compiler will have its own pragma directives. For example the #pragma pack ( ) directive (which we discussed in an earlier chapter with reference to padding of structures) is available in VC++ but not in Turbo C++.
The preprocessor also recognizes two operators: # and ##.
#include <iostream>
using namespace std;
#define disp(val) cout<<"You passed : " #val
int main( )
{
disp(20);
return 0;
}
The output is:
You passed : 20
Similarly if you write:
disp(Hi);
the output would be:
You passed : Hi
Actually, the operator # is equal to inserting two double quotation marks (this makes anything into a string).
#define conc(a,b,c) a ## b ## c
int main( )
{
cout<<conc("hi","and","bye");
return 0;
}
The output is:
hiandbye
It might seem crazy to use such operators, but it is better to know about the various features that exist. Actually, programmers rarely use these two operators.
Standard defined Macros
The compiler already has some defined macros. They are:
__FILE__ gives the filename
__LINE__ gives the line number
__DATE__ gives the date the code was compiled
__TIME__ gives the time the code was compiled
__cplusplus this is defined when the source code in compiled as a C++ code
Check out an example:
#include <iostream>
using namespace std;
int main( )
{
cout<<endl<<"Filename : "<<__FILE__;
cout<<endl<<"Line no. : "<<__LINE__;
cout<<endl<<"Compiled date : "<<__DATE__;
cout<<endl<<"Time : "<<__TIME__;
return 0;
}
The output will be:
Filename : C:\tutorial\prepro\prepro.cpp
Line no. : 7
Compiled date : Aug 10 2003
Time : 11:36:12
Beware: The standard macros start with a double underscore and end in a double underscore (it is __FILE__ not _FILE_ ).
Go back to the Contents Page 2
Copyright © 2004 Sethu Subramanian All rights reserved.