[置顶] 宏扩展和参数扫描

 

 
  

 

referrence:

http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-Prescan

Procedure

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



 

 

你可能感兴趣的:(参数)