Nested Variable Argument Macros

W

William Ahern

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
 
K

Keith Thompson

William Ahern said:
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.
 
W

William Ahern

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top