Brief introduction to c++ preprocessor

  • 2020-09-28 09:05:07
  • OfStack

A preprocessor is a set of instructions that indicate the preprocessing that the compiler needs to complete before it can actually compile.

All preprocessor instructions begin with the hash mark (#), and only the space character can precede the preprocessor instruction. Preprocessor instructions are not C++ statements, so they do not begin with a semicolon (;) At the end.

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

C++ also supports many pre-processing instructions, such as #include, #define, #if, #else, #line, etc. Let's look at these important instructions first.

# define pretreatment

The #define preprocessor directive is used to create symbolic constants. This symbolic constant is often referred to as a macro, and the common form of an instruction is:


#define macro-name replacement-text 

When this line of code appears in a file, all subsequent macros that appear in that file will be replaced with ES24en-ES25en before the program is compiled. Such as:


#include <iostream>
using namespace std;
 
#define PI 3.14159
 
int main ()
{
 
 cout << "Value of PI :" << PI << endl; 
 
 return 0;
}

Now, let's test this code and see the results of the preprocessing. Assuming the source file already exists, then compile with the -ES29en option and redirect the results to ES30en.p. Now, if you look at the test.p file, you will see that it already contains a lot of information, and the value at the bottom of the file has been changed to the following:


$ gcc -E test.cpp > test.p

...
int main ()
{
 
 cout << "Value of PI :" << 3.14159 << endl; 

 return 0;
}

Parameters of the macro

You can use #define to define a macro with arguments as follows:


#include <iostream>
using namespace std;
 
#define MIN(a,b) (a<b ? a : b)
 
int main ()
{
 int i, j;
 i = 100;
 j = 30;
 cout <<" The smaller value is: " << MIN(i, j) << endl;
 
 return 0;
}

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

[

The smaller value is: 30

]

Conditional compilation

Several instructions can be used to selectively compile portions of the program source code. This process is called conditional compilation.

The conditional preprocessor structure is similar to the if selection structure. Take a look at this preprocessor code:


#ifdef NULL
 #define NULL 0
#endif

You can compile only at debug time, and the debug switch can be implemented using 1 macro, as shown below:


#ifdef DEBUG
 cerr <<"Variable x = " << x << endl;
#endif

If the symbolic constant DEBUG was defined before instruction #ifdef DEBUG, the cerr statements in the program are compiled. You can comment out part 1 of the program using the #if 0 statement, as follows:


#if 0
  Uncompiled code 
#endif

Let's try the following example:


#include <iostream>
using namespace std;
#define DEBUG
 
#define MIN(a,b) (((a)<(b)) ? a : b)
 
int main ()
{
 int i, j;
 i = 100;
 j = 30;
#ifdef DEBUG
 cerr <<"Trace: Inside main function" << endl;
#endif
 
#if 0
 /*  This is the comment section  */
 cout << MKSTR(HELLO C++) << endl;
#endif
 
 cout <<"The minimum is " << MIN(i, j) << endl;
 
#ifdef DEBUG
 cerr <<"Trace: Coming out of main function" << endl;
#endif
 return 0;
}

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

[

Trace: Inside main function
The minimum is 30
Trace: Coming out of main function

]

The # and ## operators

The # and ## preprocessing operators are available in both C++ and ANSI/ISO C. The # operator converts the ES88en-ES89en token to a string enclosed in quotation marks.

See the following macro definition:


#include <iostream>
using namespace std;
 
#define MKSTR( x ) #x
 
int main ()
{
 cout << MKSTR(HELLO C++) << endl;
 
 return 0;
}

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

[

HELLO C++

]

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


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

Converted to:


#include <iostream>
using namespace std;
 
#define PI 3.14159
 
int main ()
{
 
 cout << "Value of PI :" << PI << endl; 
 
 return 0;
}
0

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


#include <iostream>
using namespace std;
 
#define PI 3.14159
 
int main ()
{
 
 cout << "Value of PI :" << PI << endl; 
 
 return 0;
}
1

When CONCAT appears in a program, its parameters are concatenated and used instead of macros. For example, CONCAT(HELLO, C++) is replaced with "HELLO C++" in the program, as shown in the following example.


#include <iostream>
using namespace std;
 
#define PI 3.14159
 
int main ()
{
 
 cout << "Value of PI :" << PI << endl; 
 
 return 0;
}
2

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

[

100

]

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


cout << concat(x, y);

Converted to:


#include <iostream>
using namespace std;
 
#define PI 3.14159
 
int main ()
{
 
 cout << "Value of PI :" << PI << endl; 
 
 return 0;
}
4

Predefined macros in C++

C++ provides 1 of the predefined macros shown in the following table:

描述
__LINE__ 这会在程序编译时包含当前行号。
__FILE__ 这会在程序编译时包含当前文件名。
__DATE__ 这会包含1个形式为 month/day/year 的字符串,它表示把源文件转换为目标代码的日期。
__TIME__ 这会包含1个形式为 hour:minute:second 的字符串,它表示程序被编译的时间。

Let's take a look at some examples of these macros:


#include <iostream>
using namespace std;
 
#define PI 3.14159
 
int main ()
{
 
 cout << "Value of PI :" << PI << endl; 
 
 return 0;
}
5

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

[

Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48

]

Above is the c++ preprocessor detailed content, more about C++ preprocessor information please pay attention to this site other related articles!


Related articles: