Macro replacement in C ++

Source: Internet
Author: User

1. Introduction
# Define CAT (x, y) x # Y
So what are the results of CAT (A, B) and CAT (a, B), c.

# Define str_impl (x) # x
# Define STR (x) str_impl (X)
What is the intention.

2. Rules
Macro replacement is part of the pre-processing of C/C ++. There are four rules in the C ++ standard to define replacement.

Rule 1: replace real parameters.
This rule describes the process of replacing macros with parameters.

For the form parameters in the macro definition, if the replacement list is not used as the # Or # operands, the corresponding real parameters are completely
Expand (equivalent to evaluate the real parameter), and then replace the form parameter in the replace list. If it is the # Or # operand,
Do not replace.

Rule 2: multiple scans.

After all the form parameters are replaced with the real parameters, the results are scanned again. If there are still replaceable macros, replace them,
Otherwise, stop.

Rule 3: recursive replacement suppression.

If you find the name of the macro that is being expanded in the replacement list, do not replace it here. Further, in the nested
If you find that the macro name has been replaced, do not replace it.

Rule 4: recursive preprocessing suppression.

If the replaced result forms a preprocessing instruction, this preprocessing instruction is not executed.

3. Instance
# Define CAT (x, y) x # Y

In CAT (a, B), c), first scan the replacement list and find that the X and Y parameters are the operands of #, then directly
The real parameter is moved without any processing and connected. The result is cat (a, B) C.

If you add
# Define xcat (x, y) CAT (x, y)
In xcat (a, B), c), evaluate X first, that is, calculate the result of xcat (a, B) first.
The value is AB. Then, Y is evaluated, and no processing is needed. The value is C. The result is cat (AB, c ).
Then apply Rule 2 to evaluate CAT (AB, c). The result is ABC.

Apparently
# Define str_impl (x) # x
# Define STR (x) str_impl (X)
The intention is to prevent # The macro is blocked by Rule 1 when it is used as a parameter.

Let's look at several examples in the C ++ standard:
# Define x 3
# Define F (a) f (x * ())
# UNDEF x
# Define x 2
# Define G F
# Define z [0]
# Define h g (~
# Define M (a) a (W)
# Define w 0, 1
# Define T (a)
F (y + 1) + f (z) % T (G) (0) + T) (1 );
G (x + (3, 4)-W) | H 5) & M (f) ^ m (m );
The results are as follows:
F (2 * (Y + 1) + F (2 * (F (2 * (Z [0]) % F (2*(0 )) + T (1 );
F (2*(2 + (3, 4)-0, 1) | f (2 *(~ 5) & F (2 * (0, 1) ^ m (0, 1 );

For the first one, it mainly involves the expansion of T (G) (0) + T) (1.
It is easy to calculate that the real parameter of T in the outermost layer is F (2 * (0) + T, and T is
The macro being expanded. Therefore, according to rule 3, the t is not processed and remains unchanged. Then, F (2 * (0) + T (1) is obtained ).

For the second, H 5) is replaced with G (~ 5), application rule 2, replaced with F (2 *(~ 5 )).
M (m) is replaced with m (W) first, and then rule 2 is replaced again, but M is replaced, so
Unchanged. Only W is replaced.

# Define STR (s) # s
# Define xstr (s) STR (s)
# Define debug (S, T) printf ("X" # s "= % d, X" # T "= % s ",\
X # S, X # T)
# Define incfile (n) Vers # N/* from previous # include example */
# Define glue (a, B) a # B
# Define xglue (a, B) glue (A, B)
# Define highlow "hello"
# Define low ", World"
Debug (1, 2 );
Fputs (STR (strncmp ("ABC \ 0d", "ABC", '\ 4')/* this goes away */
= 0) STR (: @ \ n), S );
# Include xstr (incfile (2). h)
Glue (high, low );
Xglue (high, low)

The results are as follows:
Printf ("X" "1" "= % d, X" "2" "= % s", x1, x2 );
Fputs ("strncmp (\" ABC \ 0d \ ", \" ABC \ ", '\ 4') = 0" ": @ \ n", S );
# Include "vers2.h"
"Hello ";
"Hello" ", World"

The key is glue and xglue.
For glue (high, low);, first there is a suppression of rule 1 to obtain the result of highlow;, and then the second scan to obtain
"Hello ";
Xglue (high, low) has no inhibitory effect. Therefore, evaluate the parameters to obtain high and low ", World", that is
Glue (high, low ", World ")
Then perform the connection operation to get highlow ", World", and then scan again to get "hello" ", World"

If you consider the natural connection of the string, you can get "Hello, world.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.