[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.