[vox-tech] macro arguments in C
Mark K. Kim
vox-tech@lists.lugod.org
Thu, 17 Oct 2002 15:03:08 -0700 (PDT)
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.