简体   繁体   中英

C preprocessor expansion order

I'm trying to do something using C preprocessor. I have this macros:

#define _MAX(x, y) (((x)) > ((y))) ? (x) : (y))

#define MAX1 _MAX(1,
#define MAX2 _MAX(2,0))

#define RIGHT _MAX(1,_MAX(2,0))
#define WRONG MAX1 MAX2

In this case, RIGHT gives me the right expression but WRONG , even though it's the same, expands the macro to blank.

It seems to me that's because after expanding MAX1 to _MAX(1, it detects there is a _MAX macro to expand and tries to do it without expanding the MAX2 , which haves the other half of the statement.

If I'm right, is there any way that I can delay the _MAX macro expansion until MAX2 it's expanded?

It's correct, because of the order WRONG is being expanded. First it expands the macro to

MAX1 MAX2

then it rescans that to expand it further, first it expands MAX1 to _MAX(1, and it's when rescanning this the error occurs as it doesn't find the termination of the argument list.

If you had defined WRONG as MAX1 MAX2 ) it would have expanded it without complaints (but not with the same expansion of course).

C preprocessor scans for macros after each expansion. Section 6.10.3.4 states:

After all parameters in the replacement list have been substituted and # and ## processing has taken place, all placemarker preprocessing tokens are removed. Then, the resulting preprocessing token sequence is rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.

One way to force C preprocessor to expand macro B ahead of macro A is to pass B to A as a parameter:

#define _MAX(x, y) (((x)>(y))?(x):(y))

#define MAX1(Y) _MAX(1,Y)
#define MAX2 _MAX(2,0)

#define NEW_RIGHT MAX1(MAX2)

Now MAX2 becomes an argument to MAX1 , so its content is expanded in the process of expanding MAX1 .

Demo.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM