Fixincludes - some analysis

Matthias Benkmann matthias at
Sat Jan 25 06:47:35 PST 2003

On Sat, 25 Jan 2003 11:49:49 +1100 Greg Schafer <gschafer at>

> ----------------------------------------
> stdio.h  (from glibc)
> @@ -73,9 +82,9 @@
>  #ifdef __USE_XOPEN
>  # ifdef __GNUC__
> -#  ifndef _VA_LIST_DEFINED
> -typedef _G_va_list va_list;
> -#   define _VA_LIST_DEFINED
> +typedef _G_va_list __not_va_list__;
> +#   define _DUMMY_VA_LIST_DEFINED
>  #  endif
>  # else
>  #  include <stdarg.h>
> So what's doing here?? 

Whatever it is it looks like a compatibility fix. You know how badly the
gcc and glibc teams coordinate their work. variable argument functions are
one of those close touching points between C library and compiler. Maybe
this is a non-issue for glibc-2.3.1. In any case, not fixing this if it is
indeed a problem could be bad. You don't want the compiler to use a
different notion of va_list than the library. Check the gcc and glibc
mailing list archives and changelog and especially the 
cvs log for the fixincludes script. This should shed some light on this

> ----------------------------------------
> curses.h ncusrses.h  (from ncurses)
> @@ -295,7 +304,9 @@
>  #endif
>  #ifndef _WCHAR_T
> +#ifndef __cplusplus
>  typedef unsigned long wchar_t;
> +#endif
>  #endif /* _WCHAR_T */
>  #ifndef _WINT_T
>  typedef long int wint_t;
> The intent of this one looks clear. Don't do the typedef if included in
> c++ code. I have no idea if this is good or bad. 

This makes sense. wchar_t is part of ANSI C++. As GCC 3.x is conforming to
the ANSI standard it's supposed to provide the type and the ncurses header
has no business typedefing it to something else when included in a C++

Unfortunately, the fix is only a partial fix. On a 32bit system,
eliminating this typedef will work nicely but on a 64bit system that uses
64bit longs, this fix will cause ncurses' notion of wchar_t to differ from
the official GNU system notion as documented in the glibc manual.

However, I think this is a non-issue for LFS. The header includes
<stddef.h> which should provide wchar_t so that this typedef is never
actually seen by the compiler.

My suggestion is to not fix the header.

> ----------------------------------------
> zconf.h  (from zlib)
> @@ -51,7 +60,7 @@
>  #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
>  #  define WIN32
>  #endif
> -#if defined(__GNUC__) || defined(WIN32) || defined(__386__) ||
> defined(i386)+#if defined(__GNUC__) || defined(WIN32) ||
> defined(__386__) || defined(__i386__)
>  #  ifndef __32BIT__
>  #    define __32BIT__
>  #  endif
> Looks clearly like a bug fix. But surely it won't matter to us because
> we are using __GNUC__ anyway right? Neither 3.3, 3.4 or 2.95.4 offer to
> fix this header. This begs the obvious question, is the header busted or
> not?

I suggest you contact the zlib maintainer about this.

> ----------------------------------------
> linux/a.out.h  (from kernel)
> @@ -127,7 +136,7 @@
>  #endif
> -#ifdef linux
> +#ifdef __linux__
>  #include <asm/page.h>
>  #if defined(__i386__) || defined(__mc68000__)
>  #define SEGMENT_SIZE   1024
> Dunno. Who uses a.out anyway? Dunno. Again, neither 3.3, 3.4 or 2.95.4
> offer to fix this header.

AFAIK, the macro is supposed to be called "__linux__" and not "linux" so
this again looks like a bugfix. Grep the other kernel headers to see if
there are other occurences of linux vs __linux__. If not, be brave and
post it to the linux kernel mailing list (after verifying that the newest
2.5 kernel has the same issue).

> ----------------------------------------
> linux/nls.h  (from kernel)
>  #ifndef _LINUX_NLS_H
>  #define _LINUX_NLS_H
>  #include <linux/init.h>
>  /* unicode character */
> +#ifndef __cplusplus
>  typedef __u16 wchar_t;
> +#endif
>  struct nls_table {
> Looks similar to the ncurses one above.

Not quite. On a GNU system, wchar_t is 32bits wide. So the ncurses typedef
of wchar_t to long is compatible. This typedef however apparently makes
wchar_t a 16bit quantity (__u16 sounds like unsigned 16bit). This is
completely broken. C code compiled with this header will never be
compatible with C++ code compiled with it. The fix will allow a C++
program that includes this header to compile but if the C++ program
actually uses any of the included functions without taking special
precautions, it will be broken. 

The correct fix for this would be to change the header to use a name such
as wchar_16 instead of wchar_t and to fix all programs that expect wchar_t
to be the same as __u16 to use wchar_16 instead. But that's of course
beyond the scope of LFS.

I suggest to not fix this header. I prefer getting errors/warnings during
the compilation over the possibility of silent miscompilation.
> ----------------------------------------
> X11/Xlib.h  (from xfree86)
> @@ -75,9 +84,11 @@
>  #include <stdlib.h>
>  #else
>  /* replace this with #include or typedef appropriate for your system */
> +#ifndef __cplusplus
>  typedef unsigned long wchar_t;
>  #endif
>  #endif
> +#endif
>  #if defined(ISC) && defined(USE_XMBTOWC)
>  #define wctomb(a,b)    _Xwctomb(a,b)

This seems to be a non-issue as the whole code portion is only seen by the
compiler if X_WCHAR is defined. This in turn is only defined if
X_NOT_STDC_ENV is defined. This sounds suspiciously like "not a standard C
environment" and certainly does NOT apply to LFS. I have verified that on
my system, X_WCHAR is NOT being defined, so the compiler never sees the
typedef which renders the fix unnecessary.


Want to learn long division in ternary?
Contact me at ICQ 2101001122212.01/0.00002

Unsubscribe: send email to listar at
and put 'unsubscribe lfs-dev' in the subject header of the message

More information about the lfs-dev mailing list