[comp.lang.c] Solution to "Varargs for Macros"

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

My original question was:
> 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.
>
> Maybe this could be done with elipses:
>   #define WRITE(fd, buf, bytes, fmt, ...) \
>      if (write(fd,buf,bytes) != bytes) \
>         fprintf(stderr, fmt, ...), exit(1)

Three people responsed.

One said that such a feature had been considered for ANSI C, but dropped 
due to lack of interest.

Another said,
    Our cpp does this.  However, instead of using elipses in the macro
    body, the extra args are lumped into the final arg.  For example:
    #define WRITE(fd, buf, bytes, fmt, ...) \
       if (write(fd,buf,bytes) != bytes) \
          fprintf(stderr, fmt), exit(1)
      - David Tanguay

But the most interesting one said,
    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!!

Sure enough, good old cpp can do it just fine.
-- 
   Dan Kegel
   srs!dan@cs.rochester.edu  dan%srs.uucp@cs.rochester.edu  rochester!srs!dan