This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: FYI, recent gcc vs. glibc's `#define printf(...' vs texinfo-4.0b
- To: Jim Meyering <jim at meyering dot net>
- Subject: Re: FYI, recent gcc vs. glibc's `#define printf(...' vs texinfo-4.0b
- From: "Zack Weinberg" <zackw at stanford dot edu>
- Date: Wed, 2 May 2001 14:44:41 -0700
- Cc: Karl Berry <karl at freefriends dot org>, bug-gcc at gnu dot org, bug-glibc at gnu dot org
- References: <urypudrk7lb.fsf@ixi.eng.ascend.com>
On Wed, May 02, 2001 at 07:02:08PM +0200, Jim Meyering wrote:
> Using the very latest gcc, as checked out a couple of hours ago,
> and Debian unstable's libc-2.2.2, I tried to build texinfo-4.0b
> (ftp://texinfo.org/texinfo/pretests/texinfo-4.0b.tar.gz)
> but was surprised to get this failure:
>
> info.c:8:1: directives may not be used inside a macro argument
> info.c:8:1: unterminated argument list invoking macro "printf"
The library is allowed to define whatever functions it wishes as
macros, so long as the function exists in case you #undef the macro
(with some explicit exceptions such as va_arg()). glibc in my opinion
defines too many macros which fail to optimize as well as Ulrich
thinks they do, but that's beside the point.
The compiler is not obliged to accept directives inside the argument
list of a macro - C99 6.10.3 para 11:
... If there are sequences of preprocessing tokens within
[a macro's] list of arguments which would otherwise [[if not
found inside a macro argument list]] act as preprocessing
directives, the behavior is undefined.
GCC chooses to make this a hard error. Older versions of GCC did
accept this, but the new tokenizing preprocessor is not set up to
handle it. Other compilers have been observed to silently mangle your
code if you use this construct.
> #define printf(fmt, args...) fprintf (stdout, fmt, ## args)
>
> static void
> info_short_help ()
> {
> printf ("%s",
> #ifdef __MSDOS__
> "a"
> #else
> "b"
> #endif
> );
> }
Suggest you rewrite this as
static void
info_short_help ()
{
#ifdef __MSDOS__
printf ("%s", "a");
#else
printf ("%s", "b");
#endif
}
This isn't currently covered in the cpp manual but I'll make a note to
include it in the rewrite I'm working on.
zw