Date: Fri, 25 Feb 2000 21:46:17 -0800 From: Alfred Perlstein <bright@wintelcom.net> To: cjclark@home.com Cc: Marco Molteni <molter@csl.sri.com>, freebsd-chat@FreeBSD.ORG Subject: Re: how to do this C preprocessor trick? Message-ID: <20000225214616.U21720@fw.wintelcom.net> In-Reply-To: <20000226001121.A20702@cc942873-a.ewndsr1.nj.home.com>; from cjc@cc942873-a.ewndsr1.nj.home.com on Sat, Feb 26, 2000 at 12:11:22AM -0500 References: <20000225182432.A5017@sofia.csl.sri.com> <20000226001121.A20702@cc942873-a.ewndsr1.nj.home.com>
next in thread | previous in thread | raw e-mail | index | archive | help
* Crist J. Clark <cjc@cc942873-a.ewndsr1.nj.home.com> [000225 21:36] wrote:
> On Fri, Feb 25, 2000 at 06:24:32PM -0800, Marco Molteni wrote:
> > Hi all,
> >
> > I have a function that takes a variable number of arguments:
> >
> > void d_printf(const char *format, ...)
> >
> > I would like to make it print automatically the function name
> > from which it is called, eg instead of doing
> >
> > f() { d_printf("f: blabla", x, y, z); }
> >
> > doing simply
> >
> > f() { d_printf("blabla", x, y, z); }
> >
> > To do that, I though of wrapping d_printf() around a macro like
> >
> > #define dprintf(x) d_printf(__FUNCTION__, x)
> >
> > but whatever combination I use (also with #), the thing is not going to work:
> >
> > main.c:231: macro `d_printf' used with too many (4) args
> >
> > Is it possible to trick the C preprocessor to do what I want?
>
> Yeah, I use the same type of thing to produce error messages. I'm
> having a little bit of trouble understanding exactly what you are
> trying to do above, so I'll just show my solution to my problem.
>
> I wanted to just be able to do,
>
> errmsg(char fmt, ...)
>
> But have it print,
>
> cmd(file:line)- Error message
>
> Where 'cmd' is the name of the program (the tail of argv[0]), 'file'
> is the C source file name, and 'num' is the line number.
>
> char *cmd
>
> void _errmsg(char *fmt, ... )
> {
> va_list ap;
>
> va_start(ap,fmt);
> vfprintf(stderr,fmt,ap);
> va_end(ap);
> }
>
> #define errmsg fprintf(stderr,"%s(%s:%d)- ",cmd,__FILE__,__LINE__); _errmsg
>
>
> Gets me around the varargs in the precompiler by not using _any_
> args in the macro. So,
>
> errmsg("cannot fine file: %s\n",str);
>
> Expands to,
>
> fprintf(stderr,"%s(%s:%d)- ",cmd,__FILE__,__LINE__); _errmsg("cannot fine file: %s\n",str);
>
> And you know, it works. Big help in debugging big apps. When it's sent
> bound for users, I make the messages a bit less verbose, but only
> takes the one change.
One of the nasty side effects is that this makes the macro expand to
multiple statements.
what's so bad about that?
if (foo < 0)
errmsg("foo < 0");
Macros that expand to multiple statements ought to be enclosed in a
do { } while(0) loop.
Although the extra parens are ugly, it things a bit safer/cleaner.
-Alfred
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-chat" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000225214616.U21720>
