YouTip LogoYouTip

Cpp Preprocessor

C++ Preprocessor \n\n

The preprocessor is a set of directives that instruct the compiler on what to do before the actual compilation begins.

\n\n

All 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\n

We have already seen the #include directive in all previous examples. This macro is used to include header files into the source file.

\n\n

C++ 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\n

The #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\n

When 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\n

Now, 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\n

Parameterized Macros

\n\n

You 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\n

When the above code is compiled and executed, it produces the following result:

\n\n
The smaller value is: 30\n
\n\n

Conditional Compilation

\n\n

There are several directives that allow you to selectively compile parts of your program's source code. This process is called conditional compilation.

\n\n

The 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\n

You 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\n

If 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\n

Let's try the following example:

\n\n

Example

\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\n

When the above code is compiled and executed, it produces the following result:

\n\n
Trace: Inside main function\nThe minimum is 30\nTrace: Coming out of main function\n
\n\n

The # and ## Operators

\n\n

The # and ## preprocessor operators are available in C++ and ANSI/ISO C. The # operator converts the replacement-text token into a quoted string.

\n\n

Look at the following macro definition:

\n\n

Example

\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\n

When the above code is compiled and executed, it produces the following result:

\n\n
HELLO C++\n
\n\n

Let's see how it works. It is not difficult to understand that the C++ preprocessor transforms the following line:

\n\n
cout << MKSTR(HELLO C++) << endl;\n
\n\n

into the following:

\n\n
cout << "HELLO C++" << endl;\n
\n\n

The ## operator is used to concatenate two tokens. Here is an example:

\n\n
#define CONCAT( x, y ) x ## y\n
\n\n

When 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\n

Example

\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\n

When the above code is compiled and executed, it produces the following result:

\n\n
100\n
\n\n

Let's see how it works. It is not difficult to understand that the C++ preprocessor transforms the following line:

\n\n
cout << concat(x, y);\n
\n\n

into the following:

\n\n
cout << xy;\n
\n\n

Predefined Macros in C++

\n\n

C++ provides the following predefined macros as shown in the table below:

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
MacroDescription
__LINE__This will contain the current line number of the program when it is compiled.
__FILE__This will contain the current file name of the program when it is compiled.
__DATE__This will contain a string of the form month/day/year, which is the date when the source file was compiled into object code.
__TIME__This will contain a string of the form hour:minute:second, which is the time when the program was compiled.
\n\n

Let's look at an example of these macros:

\n\n

Example

\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\n

When the above code is compiled and executed, it produces the following result:

\n\n
Value of __LINE__ : 6\nValue of __FILE__ : test.cpp\nValue of __DATE__ : Feb 28 2011\nValue of __TIME__ : 18:52:48\n
← Lua FunctionsIf Else Statement In Lua β†’