The preprocessor directives in C++
The preprocessor is a unique feature of C++. In C++, we have steps like compilation, linking and execution for a typical program. In reality, we have a lot of other features in a C++ program that needs to be processed before passing the program for compilation.
For this purpose, a special step called preprocessing is carried out. Preprocessing is carried out before the compilation process and the special features are preprocessed. As a result, an expanded C++ program is obtained and then it is passed to the compiler.
In this tutorial, we will explore the various preprocessor directives supported by C++.
File Inclusion Directives
#include
File inclusion directive #include allows us to include other files in our source program. We can include any header file that contains definitions of various predefined functions in our program using these functions. We can include header files in our program using the following syntax.
#include <filename>
Example:#include <iostream>
We have already seen this in our C++ programs. The header iostream contains the functions required for input/output data streaming like cout, cin, etc.
As our programs grow larger or the functionality becomes complex, we might want to divide our program into various files or import functionality from the other files. In this case, we make use of user-defined files. To include user-defined files in our program we can make use of the following syntax of #include directive
include “filename”
Example: #include “vector_int.h”
This is a user-defined header file that we intend to include in our program in order to use its functionality.
The below code Example shows the usage of the #include directive.
#include <iostream>
using namespace std;
int main()
{
cout<<"This is an example demonstrating inclusion directive #include";
}
Output:
This is an example demonstrating the inclusion directive #include.
As shown, we have used the #include directive to include the functionality of the <iostream> header in our program.
Macro Definition Directives
#define
The #define directive is used to define the symbolic constants or macros in C++ program.
The general form of a #define directive is:
#define macro_name replacement code
When a preprocessor encounters the macro in the program, the preprocessor replaces this macro with the code that is defined using the #define directive before the code is passed to the compiler.
The below code Example shows a symbolic constant RADIUS that is defined using #define directive and its usage in the program.
#include <iostream>
#define RADIUS 5
using namespace std;
int main()
{
cout<<"Area of a circle : "<<3.142 * RADIUS * RADIUS;
}
Output:
Area of a circle : 78.55
As shown in the program, we can make use of symbolic constant RADIUS in our code and it will be replaced by the value defined for it using the #define directive.
We can use the #define directive to define a proper function code. These functions are usually small functions.
An example is shown below.
#include <iostream>
#define REC_AREA(length, breadth) (length * breadth)
using namespace std;
int main()
{
int length = 20, breadth = 5, area;
area = REC_AREA(length, breadth);
cout << "Area of a rectangle is: " << area;
return 0;
}
Output:
Area of a rectangle is: 100
Here using the #define directive we have defined a function REC_AREA that takes two arguments i.e. length and breadth and calculates the area of a rectangle. In the main function, we just make use of this macro and supply two arguments to it to obtain the area of a rectangle.
#undef
Macros in a program defined with the #define directive last until it is undefined using the #undef directive. Once the program encounters #undef, the subsequent use of macro (undefined by #undef) will give a compilation error.
In the above program, if we just give a statement #undef REC_AREA after the integer declarations, then the program will give a compilation error.
Conditional Compilation Directives
Apart from the directives explained above, C++ also provides the following directives that can be used for conditional compilation of code. These directives can be used on similar lines of the if-else statement of C++.
For Example, we can set DEBUG for a program ON or OFF using these conditional directives.
Some of the conditional compilation directives provided in C++ include:
#if
#elif
#endif
#ifdef
#ifndef
#else
The below program demonstrates the usage of conditional compilation directives in a C++ program.
#include <iostream>
using namespace std;
#define DEBUG
#define MAX(a,b) (((a)>(b)) ? a : b)
int main () {
int i, j;
i = 100;
j = 50;
#ifdef DEBUG
cout <<"Trace: Start of main function" << endl;
#endif
cout <<"The maximum is " << MAX(i, j) << endl;
#undef MAX
//cout <<"The maximum is " << MAX(10,20) << endl;
#ifdef DEBUG
cout <<"Trace: End of main function" << endl;
#endif
return 0;
}
Output:
Trace: Start of main function
The maximum is 100
Trace: End of main function
In the above program, we use #ifdef – #endif directive to define a DEBUG for the program. Then we undefined the macro function MAX using the #undef directive. The conditional compilation directive constructs #ifdef – #endif checks if DEBUG is set and if it’s set, it prints few messages in the program.
The # & ## Operators
The # and ## operators are two special operators that are respectively used to convert a text token into a string to be displayed and concatenate two tokens.
Below given is an Example demonstrating both these operators.
#include <iostream>
using namespace std;
#define MKSTR( x ) #x
#define concat(a, b) a ## b
int main () {
cout <<"MKSTR(Hello World) = "<< MKSTR(Hello World) << endl;
int xy = 100;
cout <<"concat(x,y) = "<<concat(x,y);
return 0;
}
Output:
MKSTR(Hello World) = Hello World
concat(x,y) = 100
In the above program, we define MKSTR with an argument x. It has body #x. When we print this MKSTR using the argument “Hello World”, we see that because of #x, the argument is converted to a string and is displayed to the output.
Learn Python Programming Language