From owner-freebsd-chat Fri Feb 25 23:19:41 2000 Delivered-To: freebsd-chat@freebsd.org Received: from fw.wintelcom.net (ns1.wintelcom.net [209.1.153.20]) by hub.freebsd.org (Postfix) with ESMTP id 146C737BF73 for ; Fri, 25 Feb 2000 23:19:29 -0800 (PST) (envelope-from bright@fw.wintelcom.net) Received: (from bright@localhost) by fw.wintelcom.net (8.9.3/8.9.3) id XAA02923; Fri, 25 Feb 2000 23:49:09 -0800 (PST) Date: Fri, 25 Feb 2000 23:49:09 -0800 From: Alfred Perlstein To: cjclark@home.com Cc: Marco Molteni , freebsd-chat@FreeBSD.ORG Subject: Re: how to do this C preprocessor trick? Message-ID: <20000225234909.W21720@fw.wintelcom.net> References: <20000225182432.A5017@sofia.csl.sri.com> <20000226001121.A20702@cc942873-a.ewndsr1.nj.home.com> <20000225214616.U21720@fw.wintelcom.net> <20000226003741.C20702@cc942873-a.ewndsr1.nj.home.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0.1i In-Reply-To: <20000226003741.C20702@cc942873-a.ewndsr1.nj.home.com>; from cjc@cc942873-a.ewndsr1.nj.home.com on Sat, Feb 26, 2000 at 12:37:41AM -0500 Sender: owner-freebsd-chat@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org * Crist J. Clark [000225 22:02] wrote: > On Fri, Feb 25, 2000 at 09:46:17PM -0800, Alfred Perlstein wrote: > > * Crist J. Clark [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. > > Why a, > > do { } while(0) > > Rather than just, > > { } I really don't remeber offhand, I know a lot of macros in FreeBSD are moved from #define foo { bar; baz; } to #define foo do{ bar; baz; }while(0) I think it has to do with the fact that '{ .. }' is not a statement, but a block, it will break in certain constructs. Check the commitlogs and cross reference the code that was fixed by macros being changed to do/while in the tree. > That's how I group multi-statement macros, but that does not work for > this one. You should use do/while > > I just saw your answer and I guess it boils down to which is more ugly > and which is easier to forget to do properly, > > Yours, > > d_printf((fmt,arg1,arg2)); > > Or mine, > > { d_printf(fmt,arg1,arg2); } > > Extra pair of parenthesis or extra pair of curly brackets? ;) > > Or am I overlooking another vulnerability? It's easy to forget the braces and it will slip by most likely without a compile time warning, it's safer to do it our way. -- -Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-chat" in the body of the message