"Numerical Recipes in C" is nonportable code

Walter Bright bright at Data-IO.COM
Tue Aug 30 04:11:50 AEST 1988


In article <531 at accelerator.eng.ohio-state.edu> rob at kaa.eng.ohio-state.edu (Rob Carriere) writes:
<In article <13258 at mimsy.UUCP< chris at mimsy.UUCP (Chris Torek) writes:
<< [ still on the b = malloc( foo );  bb = b - 1; code in NumRecipes ]
<<Such an implementation will ABORT ON THE COMPUTATION `b - 1',
<<possibly (indeed, preferably) at compile time.  And it is legal!
<So the standard says, they tell me.  It is also one the more flagrant
<violations of the Principle of Least Astonishment I've seen in a
<while.

On a segmented architecture, like 8086's, malloc can and does return
a value that is a pointer to the beginning of a segment. That is, there
is a 16 bit selector and a 16 bit offset, the offset portion is 0 or a
very small number. Thus, subtracting a value from the pointer could result
in a segment wrap. Trouble occurs when you do things like:
	array = malloc(MAX * sizeof(array[0]));
	for (p = &array[MAX-1]; p >= &array[0]; p--)
		...
The >= will fail, because the last p-- will cause an underflow and now
p is greater than &array[MAX]! I've encountered this many times in
porting code from Unix to PCs. The correct way to write the loop is:
	for (p = &array[MAX]; p-- > &array[0]; )
or something similar.

Please, no flames about Intel's architecture. I've heard them all for years.

The best way to learn to write portable code is to be required to port
your applications to Vaxes, 68000s, and PCs. (I have all 3 on my desk!)



More information about the Comp.lang.c mailing list