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 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.) 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 4 str (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