From owner-freebsd-hackers Wed Jul 18 10:33:28 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from axl.seasidesoftware.co.za (axl.seasidesoftware.co.za [196.31.7.201]) by hub.freebsd.org (Postfix) with ESMTP id 9178F37B405 for ; Wed, 18 Jul 2001 10:33:21 -0700 (PDT) (envelope-from sheldonh@starjuice.net) Received: from sheldonh (helo=axl.seasidesoftware.co.za) by axl.seasidesoftware.co.za with local-esmtp (Exim 3.31 #1) id 15MvD6-0002vX-00 for freebsd-hackers@FreeBSD.org; Wed, 18 Jul 2001 19:34:08 +0200 From: Sheldon Hearn To: freebsd-hackers@FreeBSD.org Subject: Weird problem in 4.3-STABLE Date: Wed, 18 Jul 2001 19:34:08 +0200 Message-ID: <11254.995477648@axl.seasidesoftware.co.za> Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Hi folks, I'm busy developing a libdaemon implementation and have come unstuck on a weird problem with functions using variable argument lists in FreeBSD 4.3-STABLE. What I really want is a static inline void function declared in a header file and included in various source files, looking something like this: static inline void xdaemonwarn(char *fmt, ...) { va_list ap; va_start(ap, fmt); if (!daemon_quiet) warn(fmt, ap); va_end(ap); return; } GCC gives "syntax error before 'void'". Fair enough. So obviously, this should be implemented as a macro. But GCC warns that ANSI C doesn't support variable arguments to macros. Fine. So I give up on any semblence of efficiency and settle for a real wrapper. This is where things get interesting. The stdarg(3) manual page says this: Unlike the varargs macros, the stdarg macros do not permit programmers to code a function with no fixed arguments. This problem generates work mainly when converting varargs code to stdarg code, but it also creates difficulties for variadic functions that wish to pass all of their argu­ ments on to a function that takes a va_list argument, such as vfprintf(3). This shouldn't apply to what I'm trying to do, because I have one fixed argument. However, the non-static, non-inline version of the code fragment above, although compiling flawlessly, has trouble at runtime. I call it with two arguments: /* char *path = "/var/run/progname.pid"; */ xdaemonwarn("mkpidfile: %s", path); I get: progname: mkpidfile: : permission denied where represents some high ascii rubbish! So far, the only way I can make this work is: 1) Declare the wrapper functions as taking a bogus, unused first parameter that is an int: void xdaemonwarn(int i __unused, const char *fmt, ...) { ... 2) In the prototype provided to dependent code (via private.h, which CAN'T be included by xdaemonwarn.c), "lie" about the function as follows: void xdaemonwarn(const char *fmt, ...); 3) In the dependent code, call the function as per the lie: /* char *path = "/var/run/progname.pid"; */ xdaemonwarn("mkpidfile: %s", path); This works as expected. I get no warnings from GCC with -Wall -ansi -pedantic and the dependent code prints the expected output. So, um, what the fsck is going on here? :-) Ciao Sheldon. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message