Print? Referrence: Procedure [cpp] macro_expand (MACRO (ARGV) {if (MACRO contain "#") | (MACRO contain "##")) {stringified ARGV | ARGV pasted with other tokens} else if (ARGV is still an macro, which ARGV = NEW_MACRO (NEW_ARGV) {/* that is to say macro_expand (ARGV) ARGV = NEW_MACRO (NEW_ARGV) */macro_expand (NEW_MACRO (NEW_ARGV ))} else/* ARGV is a plain argument */{expand the MACRO with argument ARGV} macro_expand (MACRO (ARGV) {if (MACRO contain "#") | (MACRO contain "#") {stringified ARGV | ARGV pasted with other tokens} else if (ARGV is still an macro, which ARGV = NEW_MACRO (NEW_ARGV )) {/* that is to say macro_expand (ARGV) ARGV = NEW_MACRO (NEW_ARGV) */macro_expand (NEW_MACRO (NEW_ARGV ))} else/* ARGV is a plain argument */{expand the MACRO with argument ARGV} three examples First example: [cpp] # define AFTERX (x) X _ # x # define XAFTERX (x) AFTERX (x) # define TABLESIZE 1024 # define bufsize tablesize then AFTERX (BUFSIZE) expands to X_BUFSIZE, and XAFTERX (BUFSIZE) expands to X_1024. (Not to X_TABLESIZE. prescan always does a complete expansion .) # 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. [cpp] # define xstr (s) str (s) # define str (s) # s # define foo 4 str (foo) => "foo" xstr (foo) ==> xstr (4) ==> str (4) ==> "4" # 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: [cpp] # 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 # 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