summaryrefslogtreecommitdiff
blob: 012a487a954b97b9a1f6d34534cb1d0e1a7282a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
Conformance of the GNU libc with various standards
==================================================

The GNU libc is designed to be conformant with existing standard as
far as possible.  To ensure this I've run various tests.  The results
are presented here.


Open Group's hdrchk
===================

The hdrchk test suite is available from the Open Group at

	ftp://ftp.rdg.opengroup.org/pub/unsupported/stdtools/hdrchk/

I've last run the suite on 2004-04-17 on a Linux/x86 system running
a Fedora Core 2 test 2 + updates with the following results [*]:

	FIPS		No reported problems

	POSIX90		No reported problems

	XPG3		Prototypes are now in the correct header file

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** Starting unistd.h
Missing: extern char *  cuserid();
Missing: extern int     rename();
*** Completed unistd.h
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	XPG4		Prototype is now in the correct header file
			and the _POSIX2_C_VERSION symbol has been removed

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** Starting unistd.h
Missing: extern char *  cuserid();
Missing: #define        _POSIX2_C_VERSION       (-1L)
*** Completed unistd.h
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	POSIX96		Prototype moved
			(using "base realtime threads" subsets)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** Starting unistd.h
Missing: extern int     pthread_atfork();
*** Completed unistd.h
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	UNIX98		Prototypes moved and _POSIX2_C_VERSION removed
			(using "base realtime threads mse lfs" subset)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** Starting unistd.h
Missing: extern char *  cuserid();
Missing: #define        _POSIX2_C_VERSION       (-1L)
Missing: extern int     pthread_atfork();
*** Completed unistd.h
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


That means all the reported issues are due to the headers having been
cleaned up for recent POSIX/Unix specification versions.  Duplicated
prototypes have been removed and obsolete symbols have been removed.
Which means that as far as the tests performed by the script go, the
headers files comply to the current POSIX/Unix specification.


[*] Since the scripts are not clever enough for the way gcc handles
include files (namely, putting some of them in gcc-local directory) I
copied over the iso646.h, float.h, and stddef.h headers and ignored the
problems resulting from the split limits.h file).


Technical C standards conformance issues in glibc
=================================================

If you compile programs against glibc with __STRICT_ANSI__ defined
(as, for example, by gcc -ansi, gcc -std=c89, gcc -std=iso1990:199409
or gcc -std=c99), and use only the headers specified by the version of
the C standard chosen, glibc will attempt to conform to that version
of the C standard (as indicated by __STDC_VERSION__):

GCC options		Standard version
-ansi			ISO/IEC 9899:1990
-std=c89		ISO/IEC 9899:1990
-std=iso9899:199409	ISO/IEC 9899:1990 as amended by Amd.1:1995 *
-std=c99		ISO/IEC 9899:1999

* glibc does not support this standard version.

(Note that -std=c99 is not available in GCC 2.95.2, and that no
version of GCC presently existing implements the full C99 standard.)

You may then define additional feature test macros to enable the
features from other standards, and use the headers defined in those
standards (for example, defining _POSIX_C_SOURCE to be 199506L to
enable features from ISO/IEC 9945-1:1996).

There are some technical ways in which glibc is known not to conform
to the supported versions of the C standard, as detailed below.  Some
of these relate to defects in the standard that are expected to be
fixed, or to compiler limitations.


Defects in the C99 standard
===========================

Some defects in C99 were corrected in Technical Corrigendum 1 to that
standard.  glibc follows the corrected specification.


Implementation of library functions
===================================

The implementation of some library functions does not fully follow the
standard specification:

C99 added additional forms of floating point constants (hexadecimal
constants, NaNs and infinities) to be recognised by strtod() and
scanf().  The effect is to change the behavior of some strictly
conforming C90 programs; glibc implements the C99 versions only
irrespective of the standard version selected.

C99 added %a as another scanf format specifier for floating point
values.  This conflicts with the glibc extension where %as, %a[ and
%aS mean to allocate the string for the data read.  A strictly
conforming C99 program using %as, %a[ or %aS in a scanf format string
will misbehave under glibc.


Compiler limitations
====================

The macros __STDC_IEC_559__, __STDC_IEC_559_COMPLEX__ and
__STDC_ISO_10646__ are properly supposed to be defined by the
compiler, and to be constant throughout the translation unit (before
and after any library headers are included).  However, they mainly
relate to library features, and the necessary magic has yet to be
implemented for GCC to predefine them to the correct values for the
library in use, so glibc defines them in <features.h>.  Programs that
test them before including any standard headers may misbehave.

GCC doesn't support the optional imaginary types.  Nor does it
understand the keyword _Complex before GCC 3.0.  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.)

glibc's <tgmath.h> implementation is arcane but thought to work
correctly; a clean and comprehensible version requires compiler
builtins.

For most of the headers required of freestanding implementations,
glibc relies on GCC to provide correct versions.  (At present, glibc
provides <stdint.h>, and GCC doesn't.)

Implementing MATH_ERRNO, MATH_ERREXCEPT and math_errhandling in
<math.h> needs compiler support: see

http://sources.redhat.com/ml/libc-hacker/2000-06/msg00008.html
http://sources.redhat.com/ml/libc-hacker/2000-06/msg00014.html
http://sources.redhat.com/ml/libc-hacker/2000-06/msg00015.html


Issues with headers
===================

There are various technical issues with the definitions contained in
glibc's headers, listed below.  The list below assumes GCC 3.3.2, and
relates to i686-linux; older GCC may lead to more problems in the
headers.

Note that the _t suffix is reserved by POSIX, but not by pure ISO C.
Also, the Single Unix Specification generally requires more types to
be included in headers (if _XOPEN_SOURCE is defined appropriately)
than ISO C permits.

<ctype.h> should not declare size_t.

<signal.h> should not declare size_t.

<stdio.h> should not declare or use wchar_t or wint_t.

<wchar.h> does not support AMD1; to support it, the functions
fwprintf, fwscanf, wprintf, wscanf, swprintf, swscanf, vfwprintf,
vwprintf, vswprintf and fwide would need to be declared when
__STDC_VERSION__ >= 199409L and not just for C99.

<wctype.h> should not declare size_t.