Date: Wed, 18 Jul 2001 19:34:08 +0200 From: Sheldon Hearn <sheldonh@starjuice.net> To: freebsd-hackers@FreeBSD.org Subject: Weird <stdarg.h> problem in 4.3-STABLE Message-ID: <11254.995477648@axl.seasidesoftware.co.za>
next in thread | raw e-mail | index | archive | help
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: <ha>: permission denied where <ha> 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?11254.995477648>