[vox-tech] macro arguments in C

Mark K. Kim vox-tech@lists.lugod.org
Thu, 17 Oct 2002 15:11:06 -0700 (PDT)


btw, getting rid of "errno" as a part of die's argument was left as an
excercise to the reader.

(actually, i just didn't realize you wanted that gone, too, but hey...
it's a good exercise.)

-Mark


On Thu, 17 Oct 2002, Mark K. Kim wrote:

> It's a hack but it works:
>
>    #define die if(\
>       (die_filename = __FILE__) && \
>       (die_function = __FUNCTION__) && \
>       (die_line = __LINE__) \
>    ) die_for_reals
>
>
>    char* die_filename;
>    char* die_function;
>    int die_line;
>
>
>    void die_for_reals(int err, const char *fmt, ...)
>    {
>       va_list args;
>
>       va_start(args, fmt);
>       fprintf(stderr, "\n\nFatal Error:\n");
>       fprintf(stderr,  "   file: %s, function: %s, line: %d\n", die_filename, die_function, die_line);
>       fprintf(stderr,  "   strerror reports: %s\n", strerror(err));
>       fprintf(stderr,  "   ");
>       vfprintf(stderr, fmt, args);
>       fprintf(stderr,  "\n");
>       exit(0);
>    }
>
> Usage:
>
>    if(condition) die(errno, "Blah %d", 5);
>
> Note the following:
>
>    - "if" is used in the "die" macro to join the macro value store
>      stage and the "die_for_reals" function call stage.  It should
>      always evaluate all three conditionals within the if statement,
>      and they should always evaluate to true, so "die_for_reals"
>      should always be called.
>
>      This "if" trick is necessary.  Otherwise you'd have to have
>      {} die, like this:
>
>         if(condition) { die(errno, "Blah %d", 5); }
>
>      which isn't desirable.
>
>    - Your die() function had a problem.  The line
>
>          vfprintf(stderr, "   %s\n", args);
>
>      was changed to:
>
>          fprintf(stderr,  "   ");
>          vfprintf(stderr, fmt, args);
>          fprintf(stderr,  "\n");
>
>      besides the modifications that were necessary to accomodate
>      the die macro trick.
>
> I used a similar trick for my database class.  I didn't have to deal with
> variable arguments, though.
>
> -Mark
>
> On Thu, 17 Oct 2002, Peter Jay Salzman wrote:
>
> > i wrote a generalized "die" function:
> >
> > void
> > die(int err, const char *file, const char *func, int line, const char *fmt, ...)
> > {
> >    va_list args;
> >
> >    va_start(args, fmt);
> >    fprintf(stderr, "\n\nFatal Error:\n");
> >    fprintf(stderr,  "   file: %s, function: %s, line: %d\n", file, func, line);
> >    fprintf(stderr,  "   strerror reports: %s\n", strerror(err));
> >    vfprintf(stderr, "   %s\n", args);
> >    exit(0);
> > }
> >
> >
> > normally, i call this function as (for example):
> >
> >    die(errno, __FILE__, __FUNCTION__, __LINE__,
> >       "you made boo-boo number %d.", boo-boo);
> >
> > that's quite a mouthful.  if possible, i'd like to use a macro to
> > shorten this to:
> >
> >    die("you made boo-boo number %d.", boo-boo);
> >
> > the problem is the "..." in the die() declaration.  i'm pretty sure that
> > macros can't take an arbitrary number of arguments.  potentially, i'd
> > like to be able to call die as:
> >
> >    die("%c%c%c%c%c" 'o', 'o', 'p', 's', '!');
> >
> > is there a way to shorten the call to die() and still transmit the
> > errno, file, function and line informatin?
> >
> > pete
> >
> > --
> > Fingerprint: B9F1 6CF3 47C4 7CD8 D33E 70A9 A3B9 1945 67EA 951D
> > _______________________________________________
> > vox-tech mailing list
> > vox-tech@lists.lugod.org
> > http://lists.lugod.org/mailman/listinfo/vox-tech
> >
>
> --
> Mark K. Kim
> http://www.cbreak.org/
> PGP key available upon request.
>
>
>
> _______________________________________________
> vox-tech mailing list
> vox-tech@lists.lugod.org
> http://lists.lugod.org/mailman/listinfo/vox-tech
>

--
Mark K. Kim
http://www.cbreak.org/
PGP key available upon request.