By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,614 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

Nested Variable Argument Macros

P: n/a
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

Jun 28 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
William Ahern <wi*****@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) ks***@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.
Jun 28 '06 #2

P: n/a
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.
Jun 29 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.