referrence:
http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-PrescanProcedure
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:
#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.
#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:
#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
作者:ssmale 发表于2013-7-17 13:47:12 原文链接
阅读:9 评论:0 查看评论