ANSI C standard library

Colin Plumb ccplumb at rose.waterloo.edu
Fri Apr 26 06:18:55 AEST 1991


steve at taumet.com (Stephen Clamage) wrote:
>ccplumb at rose.waterloo.edu (Colin Plumb) writes:
>
>>- A large fraction of the ANSI C library can't be written in *strictly
>> conforming* ANSI C.
>
> In the full posting you mentioned only setjmp and longjmp...
> Can you name any other functions in the standard C library which
> cannot reasonably be written in strictly-conforming C, or does 2%
> (3 out of about 150) constitute a "large fraction"?

Okay, let me see...
First, I'll ignore the linker tricks used so library functions can call
other library functyions even without the proper incliude files
(e.g. assert() calls abort()).  I'll also assume that you don't want
a trivial library where everything hard returns failure (e.g. clock()).

Now, let's go through the header files:
errno.h - easy to write in C, assuming knowledge of the rest of the library
	(However, machine-dependent code may require machine-dependent errors)
float.h - not possible
limits.h - not possible
stddef.h - not possible (except for NULL)
assert.h - trivial
ctype.h - a basic implementation, with the "C" locale only and only
	characters from the C character set, is possible.
locale.h - no particular difficulty
math.h - since the standard imposes no accuracy constraints, and
	HUGE_VAL is obtainable from <float.h>, there is no difficulty
	in creating a minimal library.  Of course, it will be very
	low quality, and frexp/ldexp won't use the "obvious"
	implementation.
setjmp.h - not possible
signal.h - without external interrupts, a portable version can be written,
	except for SIG_DFL, SIG_ERR and SIG_IGN.  If you have external
	interrupts, this can't be written portably.
stdarg.h - not possible
stdio.h - large parts are writeable in C, although a number of #defines
	and typedefs can't be portably declared, and remove(), rename(),
	tmpnam(), fclose(), fopen(), some low-level read/write primitives
	(fread/fwrite, fgetc/fputc, or whatever), and some seek-type
	primitives are OS-dependent.
stdlib.h - A mixed bag.  As with <math.h>, a good strtod()
	isn't really possible, and malloc()/free() aren't portably
	writeable, nor is a realloc() that attempts to expand in place.
	exit(), of course, is non-portable, along with EXIT_FAILURE.
	getenv() isn't portable, and system() is the pits.  div() and
	ldiv() are here because they're uglay and inefficient in plain
	C, although writeable with the help of <limits.h>.  I'm not
	really sufficiently familiar with the multibyte stuff to see
	what interactions it has, although if you know the character
	sets, everything here is writeable in C.
string.h - memmove(), as I mentioned, is disgusting in strictly conforming C,
	and many of the other routines benefit greatly from low-level
	implmeementations, although there's no great loss from writing them
	in C.  strcoll() and strxfrm() depend on the locale stuff,
	if you're implementing non-C locales.  strerror() depends
	on any machine-dependencies in <errno.h>.
time.h - tm_isdst is difficult (assuming you don't punt), clock() and
	time() are, of course, non-portable, and the others all depend
	on time_t.  If you implement Unix-style unsigned long seconds
	since epoch, then everything else is portably writeable.

Does that give some idea of the size of the problem?  If you pick some
primitives to write it in terms of, you can write almost everything
in Strictly Conforming C, and a great deal more in semi-portable
C, but there are a lot of gtchas hiding in there.
-- 
	-Colin



More information about the Comp.std.c mailing list