[comp.lang.c] Varargs for Macros?

dan@srs.UUCP (Dan Kegel) (02/20/88)

We now have a nice standard way of writing functions that take variable
numbers of arguments.  Is there any corresponding capability for macros?

For example, I'd like to have a macro that calls write() and prints a fancy
error message upon failure.  It would expand this
  WRITE(fd, buf, bytes, "Error at record %d of %s", recNum, fileName);
to this:
  if (write(fd, buf, bytes) != bytes)
     fprintf(stderr, "Error at record %d of %s", recNum, fileName), exit(1);
regardless of the number of arguments to fprintf.

This example is a little poor, I admit, but it demonstrates passing a
variable number of parameters to a macro.

I suppose the macro definition might use elipses:
#define WRITE(i, p, n, s, ...)     \
    if (write(i, p, n) != n)       \
	fprintf(stderr, s, ...),   \
	exit(1)

Anybody else ever want to do this sort of thing?
-- 
   Dan Kegel
   srs!dan@cs.rochester.edu  dan%srs.uucp@cs.rochester.edu  rochester!srs!dan

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/20/88)

In article <600@srs.UUCP> dan@srs.UUCP (Dan Kegel) writes:
>We now have a nice standard way of writing functions that take variable
>numbers of arguments.  Is there any corresponding capability for macros?

Not using the C preprocessor.  This extension was proposed and
discussed by X3J11, but it didn't gather enough support to make
it into the proposed standard.

edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (02/21/88)

> We now have a nice standard way of writing functions that take variable
> numbers of arguments.  Is there any corresponding capability for macros?

  If you are on an UNIX system try m4.  Disclaimer - I don't use m4,
so I have no idea what I'm talking about :-).


-- 

Eddie Wyatt 				e-mail: edw@ius1.cs.cmu.edu

Alan_T._Cote.OsbuSouth@Xerox.COM (02/21/88)

Dan Kegel <dan@srs.uucp> writes,

>For example, I'd like to have a macro that calls write() and prints a fancy
>error message upon failure.  It would expand this
>  WRITE(fd, buf, bytes, "Error at record %d of %s", recNum, fileName);
>to this:
>  if (write(fd, buf, bytes) != bytes)
>     fprintf(stderr, "Error at record %d of %s", recNum, fileName), exit(1);
>regardless of the number of arguments to fprintf.

If you're willing to modify your example just a little, you can get what you
want.  Try this macro:

#define WRITE(fd,buf,bytes,errparm) \
        if(write(fd,buf,bytes)!=bytes) \
          fprintf errparm, exit(1)

Here's a sample call:

WRITE(fd, buf, bytes, (stderr,"Error at record %d of %s", recNum, fileName));

Which should generate:

if(write(fd,buf,bytes)!=bytes)
        fprintf (stderr,"Error at record %d of %s", recNum, fileName), exit(1);

The trick is in the use of parentheses.

Neat, huh?!?

	- Al Cote'

PS:  No flames for tasteless style -- this is only a quickie!!