Referrence:
Http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-Prescan
Procedure
Macro_expand (macro (argv)/* macro extension process with parameters. The macro is macro and the parameter is argv */{/*. If the macro is defined as a macro containing, take the argv parameter as a string and substitute it into the macro. The result is displayed. Exit */If (macro contain "#") | (macro contain "##")) {stringified argv | argv pasted with other tokens}/* If the macro does not contain #, #, and the macro parameter argv itself is also a macro, extend the macro parameter first, the macro itself is not changed. Do not input the */else if (argv is still an macro, which argv = new_macro (new_argv) parameter first )) {/* That is to say macro_expand (argv) argv = new_macro (New _ Argv) recursion this process */macro (macro_expand (new_macro (new_argv)}/* The macro parameter is a common parameter. If it is not a macro, the result is obtained after substitution, import data from the inside and out to obtain results layer by layer. */Else/* argv is a plain argument */{expand the macro with argument argv }}
Three examples
First example:
# Define afterx (x) X _ # X # define xafterx (x) afterx (x) # define tablesize 1024 # define bufsize tablesizet1_afterx (bufsize) expands to x_bufsize, and xafterx (bufsize) expands to x_1024. (Not To x_tablesize. prescan always does a complete expansion .)
Second example:
If you want to stringify the result of expansion of a macro argument, you have to use two levels of macros.
# Define xstr (s) STR (s) # define STR (s) # s # define Foo 4str (FOO) => "foo" xstr (FOO) ==> xstr (4) ==> STR (4) ==> "4"
S is stringified when it is used in STR, so it is not macro-expanded first.
But s is an ordinary argument to xstr, so it is completely macro-expanded before xstr itself is expanded (see argument prescan ).
Therefore, by the time STR gets to its argument, it has already been macro-expanded.
Third example:
# Define a (x) B (x) + 1 # define B (X) C (x) # define C (X) # X # Define table size + 2 # define size 5/* right */A (table) ==> A (size + 2) ==> A (5 + 2) ==> B (5 + 2) + 1 ==> C (5 + 2) + 1 => "5 + 2" + 1/* wrong */A (table) => B (table) + 1 => C (table) + 1 => "table" + 1
This example is original and has passedCodeTest.
It mainly indicates that parameter extension is performed first before parameter replacement, instead of macro extension and parameter replacement.
For test code, see my space code.