This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Comparison of glibc headers and C standards, part 1


I am comparing the glibc headers against the 1990/1994/1999 C
standards.  The following were the discrepancies I found in the
headers from <assert.h> to <stdint.h> alphabetically.

All tests were done with recent glibc and GCC CVS, the headers being
preprocessed with -std=c89 / -std=iso9899:199409 / -std=c99 with and
without -O2, and with no feature test macros defined, on i686-linux.

General
=======

Defining __STDC_IEC_559__ and __STDC_IEC_559_COMPLEX__ is the
responsibility of the compiler, if it fully implements the applicable
requirements of Annex F (respectively G) and has information that the
library implements its part.  This in turn depends on adequately
conforming hardware.  It's not the job of <features.h>; C99 6.10.8p3
requires that the values of these macros are constant throughout the
translation unit.

GCC doesn't support the optional imaginary types.  Nor does it
understand the keyword _Complex.  This has the corresponding impact on
the relevant headers.

glibc's use of extern inline conflicts with C99: in C99, extern inline
means that an external definition is generated as well as possibly an
inline definition, but in GCC it means that no external definition is
generated.  When GCC's C99 mode implements C99 inline semantics, this
will break the uses of extern inline in glibc's headers.  (Actually,
glibc uses `extern __inline', which is beyond the scope of the
standard, but it would clearly be very confusing for `__inline' and
plain `inline' to have different meanings in C99 mode.)

complex.h
=========

Some inline functions use ~ for complex conjugation; as this is a C99
constraint violation (6.5.3.3p1), __extension__ should probably be
used here.

ctype.h
=======

This header should not declare size_t (which gets declared via
<bits/types.h>).  (POSIX.1 generally reserves the _t suffix, but pure
ISO C does not.)

For C99, this header should declare the isblank function (7.4.1.3).
(Because of the reservation of names beginning with `is' and a
lowercase letter, such a declaration is safe, though unnecessary, for
the old standard as well.)

fenv.h
======

feclearexcept, fegetexceptflag, feraiseexcept, fesetexceptflag,
fegetenv, fesetenv and feupdateenv are specified by C99 as returning
void, not int.  Clive Feather proposed in DR#202 that this should
change between the FDIS and the standard, but that didn't happen; the
int returns were included in a draft TC proposed to come out
simultaneously with the standard, but that didn't happen either.  I
presume the int returns are deliberate in anticipation that when a TC
does come out it will include such a change?

FE_DFL_ENV should be of type `const fenv_t *', not plain `fenv_t *'.

inttypes.h
==========

Macros such as INT8_C from <stdint.h> and <inttypes.h> are not
implementable as defined by the standard without compiler extensions,
so in glibc they have the promoted type.  This is also the subject of
a DR (DR#209), with a strong expectation that the standard will be
fixed in a TC to be consistent with all other places where promoted
types are used in macros.

The functions llabs and lldiv are wrongly declared by this header when
optimisation is turned on.  __-prefixed versions of the names need to
be used instead.  (Likewise in the __WORDSIZE == 64 section, labs and
ldiv are declared.)

This header should not declare the types wchar_t or lldiv_t.  (Nor
ldiv_t when __WORDSIZE == 64.)

The limits such as UINT8_MAX for 8-bit and 16-bit types should not be
unsigned, since the relevant unsigned types promote to `int' rather
than `unsigned int'.

The types of WCHAR_MAX and WCHAR_MIN, and the value of WCHAR_MIN, are
wrong; on x86 Linux, wchar_t is `long int', so the values should be
the limits of `long int' and of that type, rather than the `int'
values (2147483647) and (0) at present.  See 7.18.3p4 and footnote
219.

The types of WINT_MAX and WINT_MIN, and the value of WINT_MAX, are
also wrong; on x86 Linux wint_t is `unsigned int'.

locale.h
========

The C99-new members of struct lconv:

  char int_p_cs_precedes;
  char int_p_sep_by_space;
  char int_n_cs_precedes;
  char int_n_sep_by_space;
  char int_p_sign_posn;
  char int_n_sign_posn;

are not in a C90-reserved namespace, so need to be __-prefixed if
__USE_ISOC99 not defined.

math.h
======

OK in C90.

For C99: DECIMAL_DIG and FLT_EVAL_METHOD should be in <float.h>,
provided by GCC (and seem to be the only C99 features missing from
GCC's <float.h>), not in <math.h>.

FP_ILOGB0 and FP_ILOGBNAN both expand to 0x80000000, which is of type
`unsigned int'.  They should be ints of the values specified in
7.12p8.

As previously discussed on libc-hacker, MATH_ERRNO, MATH_ERREXCEPT and
math_errhandling are missing.

This header should not declare `signgam'.

signal.h
========

Should not declare size_t.

stdint.h
========

Only problems (declaration of wchar_t, wrong types and values of
macros) listed above under inttypes.h.

-- 
Joseph S. Myers
jsm28@cam.ac.uk


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]