The preprocessor is a set of directives that instruct the compiler on what to do before the actual compilation begins.
\n\nAll preprocessor directives start with a hash symbol (#). Only whitespace characters can appear before a preprocessor directive. Preprocessor directives are not C++ statements, so they do not end with a semicolon (;).
\n\nWe have already seen the #include directive in all previous examples. This macro is used to include header files into the source file.
\n\nC++ supports many preprocessor directives, such as #include, #define, #if, #else, #line, etc. Let's take a look at these important directives.
\n\n#define Preprocessor
\n\nThe #define preprocessor directive is used to create symbolic constants. This symbolic constant is commonly called a macro. The general form of the directive is:
\n\n#define macro-name replacement-text\n\n\nWhen this line appears in a file, all subsequent occurrences of the macro in that file will be replaced by the replacement-text before the program is compiled. For example:
\n\n#include<iostream>\nusing namespace std;\n\n#define PI 3.14159\n\nint main()\n{\n cout << "Value of PI :" << PI << endl;\n return 0;\n}\n\n\nNow, let's test this code to see the result of preprocessing. Assuming the source code file already exists, we can compile it using the -E option and redirect the output to test.p. If you now view the test.p file, you will see it contains a lot of information, and the value at the bottom has been changed to the following:
\n\n$ gcc -E test.cpp > test.p\n...\nint main ()\n{\n cout << "Value of PI :" << 3.14159 << endl;\n return 0;\n}\n\n\nParameterized Macros
\n\nYou can use #define to define a macro with parameters, as shown below:
\n\n#include<iostream>\nusing namespace std;\n\n#define MIN(a,b)(a<b ? a : b)\n\nint main()\n{\n int i, j;\n i = 100;\n j = 30;\n cout << "The smaller value is:" << MIN(i, j) << endl;\n return 0;\n}\n\n\nWhen the above code is compiled and executed, it produces the following result:
\n\nThe smaller value is: 30\n\n\nConditional Compilation
\n\nThere are several directives that allow you to selectively compile parts of your program's source code. This process is called conditional compilation.
\n\nThe structure of conditional preprocessor directives is similar to the if selection structure. Look at the following preprocessor code:
\n\n#ifdef NULL\n #define NULL 0\n#endif\n\n\nYou can compile code only during debugging. A debug switch can be implemented using a macro, as shown below:
\n\n#ifdef DEBUG\n cerr << "Variable x = " << x << endl;\n#endif\n\n\nIf the symbolic constant DEBUG is defined before the #ifdef DEBUG directive, the cerr statement in the program will be compiled. You can use the #if 0 statement to comment out a part of the program, as shown below:
\n\n#if 0\n Code not to be compiled\n#endif\n\n\nLet's try the following example:
\n\nExample
\n\n#include<iostream>\nusing namespace std;\n\n#define DEBUG\n\n#define MIN(a,b)(((a)<(b)) ? a : b)\n\nint main()\n{\n int i, j;\n i = 100;\n j = 30;\n\n#ifdef DEBUG\n cerr << "Trace: Inside main function" << endl;\n#endif\n\n#if 0\n cout << MKSTR(HELLO C++) << endl;\n#endif\n\n cout << "The minimum is " << MIN(i, j) << endl;\n\n#ifdef DEBUG\n cerr << "Trace: Coming out of main function" << endl;\n#endif\n\n return 0;\n}\n\n\nWhen the above code is compiled and executed, it produces the following result:
\n\nTrace: Inside main function\nThe minimum is 30\nTrace: Coming out of main function\n\n\nThe # and ## Operators
\n\nThe # and ## preprocessor operators are available in C++ and ANSI/ISO C. The # operator converts the replacement-text token into a quoted string.
\n\nLook at the following macro definition:
\n\nExample
\n\n#include<iostream>\nusing namespace std;\n\n#define MKSTR(x) #x\n\nint main()\n{\n cout << MKSTR(HELLO C++) << endl;\n return 0;\n}\n\n\nWhen the above code is compiled and executed, it produces the following result:
\n\nHELLO C++\n\n\nLet's see how it works. It is not difficult to understand that the C++ preprocessor transforms the following line:
\n\ncout << MKSTR(HELLO C++) << endl;\n\n\ninto the following:
\n\ncout << "HELLO C++" << endl;\n\n\nThe ## operator is used to concatenate two tokens. Here is an example:
\n\n#define CONCAT( x, y ) x ## y\n\n\nWhen CONCAT appears in the program, its parameters are concatenated and used to replace the macro. For example, CONCAT(HELLO, C++) in the program is replaced by "HELLO C++", as shown in the following example.
\n\nExample
\n\n#include<iostream>\nusing namespace std;\n\n#define concat(a, b) a ## b\n\nint main()\n{\n int xy = 100;\n cout << concat(x, y);\n return 0;\n}\n\n\nWhen the above code is compiled and executed, it produces the following result:
\n\n100\n\n\nLet's see how it works. It is not difficult to understand that the C++ preprocessor transforms the following line:
\n\ncout << concat(x, y);\n\n\ninto the following:
\n\ncout << xy;\n\n\nPredefined Macros in C++
\n\nC++ provides the following predefined macros as shown in the table below:
\n\n| Macro | \nDescription | \n
|---|---|
| __LINE__ | \nThis will contain the current line number of the program when it is compiled. | \n
| __FILE__ | \nThis will contain the current file name of the program when it is compiled. | \n
| __DATE__ | \nThis will contain a string of the form month/day/year, which is the date when the source file was compiled into object code. | \n
| __TIME__ | \nThis will contain a string of the form hour:minute:second, which is the time when the program was compiled. | \n
Let's look at an example of these macros:
\n\nExample
\n\n#include<iostream>\nusing namespace std;\n\nint main()\n{\n cout << "Value of __LINE__ : " << __LINE__ << endl;\n cout << "Value of __FILE__ : " << __FILE__ << endl;\n cout << "Value of __DATE__ : " << __DATE__ << endl;\n cout << "Value of __TIME__ : " << __TIME__ << endl;\n return 0;\n}\n\n\nWhen the above code is compiled and executed, it produces the following result:
\n\nValue of __LINE__ : 6\nValue of __FILE__ : test.cpp\nValue of __DATE__ : Feb 28 2011\nValue of __TIME__ : 18:52:48\n
YouTip