Fixincludes - some analysis

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


On Sat, 25 Jan 2003 11:49:49 +1100 Greg Schafer <gschafer at zip.com.au>
wrote:

> ----------------------------------------
> 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
> +#  ifndef _DUMMY_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
issue.

> 
> ----------------------------------------
> 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++
program.

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 @@
>  #define SEGMENT_SIZE PAGE_SIZE
>  #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.

MSB

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

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



More information about the lfs-dev mailing list