dan@rna.UUCP (Dan Ts'o) (04/18/88)
The code below seems okay and does passed thru SUN's C compiler fine,
but the 4.3BSD C compiler misgenerates a label, causing an assembler error
messages and an unknown external (during loading). (Yes, I know that z is not
used. Its removal has no effect on the problem.)
/* Shellsort */
fsort(a, z, n)
register double *a;
register unsigned z, n;
{
double w;
register unsigned i, j, k;
k = 1;
n++;
do {
k = 3*k + 1;
} while (k <= n);
for (k /= 3; k > 0; k /= 3) {
for (i = k; i < n; i++) {
w = a[i];
for (j = i - k; (j >= 0) && (a[j] > w); j -= k)
a[j + k] = a[j];
a[j] = w;
}
}
}
Thanks.chris@trantor.umd.edu (Chris Torek) (04/18/88)
In article <153@rna.UUCP> dan@rna.UUCP (Dan Ts'o) writes: > The code below seems okay and does passed thru SUN's C compiler fine, >but the 4.3BSD C compiler misgenerates a label, causing an assembler error >messages and an unknown external (during loading). As you might guess, it is a bug in the compiler, or more precisely, a bug in the optimiser, which goofs `tst' instructions that are not followed by a branch. Specifically: > register unsigned i, j, k; [stuff deleted] > for (j = i - k; (j >= 0) && (a[j] > w); j -= k) The test `j >= 0' is always true, so the compiler generates tstl rJ # is it < 0? cmpd ... # no!, so do the other half of the && expression Removing the `j >= 0' test from the source stops the optimiser from botching its job, although the code is wrong either way. Replacing the loop with for (j = i - k; (int)j >= 0 && a[j] > w; j -= k) also does the trick, and incidentally fixes the sort; alternatively, declare j as `int' rather than `unsigned'. -- In-Real-Life: Chris Torek, Univ of MD Computer Science, +1 301 454 7163 Domain: chris@mimsy.umd.edu Path: ...!uunet!mimsy!chris