[comp.lang.c] Commas in macro arguments

peter@ficc.uu.net (Peter da Silva) (03/26/90)

> >#define call(a,b)	a(b)

> >I can use that to call a function with one argument. How can I use
> >it to call a function with two arguments? In other words: How do I
> >pass a string containing a comma as the second argument to the macro?

> You can't.

Sometimes you can, depending on how much you want to munge the arguments:

#define call(a,b) a b

call(a,(b))
call(c,(d,e))
-- 
 _--_|\  `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
/      \  'U`
\_.--._/
      v

jeff@samna.UUCP (jeff) (03/29/90)

In article <T9H20-9ggpc2@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>> >#define call(a,b)	a(b)
>
>> >I can use that to call a function with one argument. How can I use
>> >it to call a function with two arguments?
>
>Sometimes you can, depending on how much you want to munge the arguments:
>
>#define call(a,b) a b
>
>call(a,(b))
>call(c,(d,e))

I sometimes use this mechanism to put debugging printf's in source
files (Can be used for any variable argument macro).

Debugging statements are written like this:

	DPRINTF(("Variable x=%d, y=%d, z=%d\n", x, y, z));


Then in a header file:

#ifdef	DEBUG
#	define	DPRINTF(s) printf s
#else
#	define	DPRINTF(s)
#endif


Sometimes it's kinda hard to remember the extra set of parentheses, but...

Jeff

mcdaniel@amara.uucp (Tim McDaniel) (04/11/90)

   esp_003@jhunix.UUCP (Stdnt003) writes:
   >#define	call(a, b)	a ## b		/* (See K&R for details) */

("K&R" means 2nd Edition Kernighan and Richie)

Excuse me if this has already been pointed out, but it's my
understanding that this would be illegal for the purpose.

Page 230 of K&R2: "just after replacement of the parameters, each ##
is deleted, together with any white space on either side, so as to
concatenate the adjacent tokens and form a new token.  The effect is
undefined if invalid tokens are produced..."  The example on page 231
is more explicit:

       "#define	cat(x, y)     x ## y
... the call cat(cat(1,2),3) is undefined: the presence of ## prevents
the arguments of the outer call from being expanded.  Thus it produces
the token string
	cat	(	1	,	2	)3
and ')3' (the concatenation of the last token of the first argument
with the first token of the second) is not a legal token."

I conclude that
	call(foo,(a,b))
need not produce
	foo(a,b)
It conceptually first produces the token "foo(", which is not a legal
token.  (Of course, since the behavior is undefined, the compiler
could do what Stdnt003 expected---but it need not, and an integrated
preprocessor-compiler program probably won't.)

--
Tim McDaniel
Applied Dynamics International, Ann Arbor, MI
Internet: mcdaniel%amara.uucp@mailgw.cc.umich.edu
UUCP: {uunet,sharkey}!amara!mcdaniel

karl@haddock.ima.isc.com (Karl Heuer) (04/11/90)

In article <MCDANIEL.90Apr10154614@orenda.amara.uucp> mcdaniel@amara.uucp (Tim McDaniel) writes:
>
>   esp_003@jhunix.UUCP (Stdnt003) writes:
>   >#define	call(a, b)	a ## b		/* (See K&R for details) */
>
>[This isn't legal, since `##' is expecting to produce a valid token.]

That is correct.  However, in this case there was no reason to use the paste
operator anyway.  The simpler construct
	#define	call(a, b) a b
does what Stdnt003 intended.

Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint