Home > Archive > C > June 2006 > Nested Variable Argument Macros
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Nested Variable Argument Macros
|
|
| William Ahern 2006-06-28, 6:56 pm |
| So, I recently learned that Solaris doesn't, or doesn't seem, to provide
err.h. On some platforms err.h provides simple wrappers for error printing
to stderr. One of which, err(), has this signature:
void err(int exit_code, const char *fmt, ...);
It will print fmt + ... to stderr, tacking on a colon, the
result of strerror(errno), and a newline. Then it exits.
As a workaround, assuming that `fmt' will be passed as a string
literal, I came up w/ these macros to mimic err():
#define err__(ret, fmt, ...) do { \
fprintf(stderr, fmt ": %s\n", __VA_ARGS__); \
exit((ret)); \
} while(0)
#define err(ret, ...) \
err__(ret, __VA_ARGS__, strerror(errno))
This seems to work for me using two different compilers (GCC, TinyCC) on
two different platforms. Still, that doesn't resolve the standard
compliance issue. Any comments? I realize variable arguments macros were
defined by C99 only. Still, I'm curious whether this should have
well-defined behavior, as far as the standard is concerned.
- Bill
| |
| Keith Thompson 2006-06-28, 6:56 pm |
| William Ahern <william@25thandClement.com> writes:
> So, I recently learned that Solaris doesn't, or doesn't seem, to provide
> err.h. On some platforms err.h provides simple wrappers for error printing
> to stderr. One of which, err(), has this signature:
>
> void err(int exit_code, const char *fmt, ...);
>
> It will print fmt + ... to stderr, tacking on a colon, the
> result of strerror(errno), and a newline. Then it exits.
>
> As a workaround, assuming that `fmt' will be passed as a string
> literal, I came up w/ these macros to mimic err():
>
> #define err__(ret, fmt, ...) do { \
> fprintf(stderr, fmt ": %s\n", __VA_ARGS__); \
> exit((ret)); \
> } while(0)
>
> #define err(ret, ...) \
> err__(ret, __VA_ARGS__, strerror(errno))
>
> This seems to work for me using two different compilers (GCC, TinyCC) on
> two different platforms. Still, that doesn't resolve the standard
> compliance issue. Any comments? I realize variable arguments macros were
> defined by C99 only. Still, I'm curious whether this should have
> well-defined behavior, as far as the standard is concerned.
err.h is not part of the C standard.
Yes, variable arguments to macros are defined only by C99. In C90,
you can just use a function with a variable number of arguments; this
also removes the restriction that the argument needs to be a string
literal.
Since implementations are allowed to provide extensions, there's
nothing illegal about a C90 compiler providing some features of C99,
as long as it doesn't affect any strictly conforming C90 program. (No
strictly conforming C90 program can refer to __VA_ARGS__.)
Why did you define these as macros in the first place? Execution
speed shouldn't be an issue, since it exits the program anyway.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
| |
| William Ahern 2006-06-28, 6:56 pm |
| On Wed, 28 Jun 2006 23:57:12 +0000, Keith Thompson wrote:
> Why did you define these as macros in the first place? Execution speed
> shouldn't be an issue, since it exits the program anyway.
Well, it could feasibly require the least amount of work. But, mostly, I
was just curious whether calling a variable argument macro from another
variable argument macro was well defined.
_Whether_ it should be done is an entirely different topic. I'm not one to
use macros for macros' sake, anyhow. And, as you say, performance isn't an
issue, particularly when it's done once per program invocation.
|
|
|
|
|