The macro's internal representation will be like this, where spaces indicate the boundaries of the token, and #1 and #2 are magic tokens of internal use, indicating where the parameters should be replaced:
MIN( #1 , #2 ) --> ( ( #1 ) < ( #2 ) ? ( #1 ) : ( #2 ) )
- that is, the preprocessor does not use the internal parameters of the macro (in addition to implement override rules). Therefore, it does not matter that the formal parameter names match the actual arguments.
Which can cause problems when the macro body uses an identifier that is not a formal parameter name, but that identifier also appears when the formal parameter is expanded. For example, if you rewrote your MIN macro using the GNU extensions, which allow you to avoid evaluating arguments twice ...
and then you tried to use it like this:
int minint(int b, int a) { return MIN(b, a); }
the macro extension will look like this:
int minint(int b, int a) { return ({ __typeof__(b) a = (b); __typeof__(a) b = (a); a < b ? a : b; }); }
and the function will always return its first argument, regardless of whether it was smaller. C is not able to avoid this problem in the general case, but the convention that many people use is to always underline at the end of the name of each local variable defined inside the macro, and never put underscores at the ends of any other identifiers. (Contrast the behavior of hygiene macro schemes that are not guaranteed to have this problem. Generic Lisp makes you worry about it yourself, but at least you have gensym to help.)
zwol
source share