kre@munnari.OZ (Robert Elz) (11/30/85)
In article <5300@elsie.UUCP>, ado@elsie.UUCP (Arthur David Olson) writes: > Since the smart folks at Berkeley were unable to fix the problem, That's not quite right - Berkeley did "fix the problem" (which was that the compiler produced bad code) they simply made the perfectly legal decision to ignore the "register" declaration for chars & shorts. > The theory is that if > the compiler produces correct code for non-register shorts (et al.) then it > will produces correct code for register shorts provided that you make them > look like non-register shorts. Well, perhaps... Its not quite that simple. Its not terribly hard to make the compiler produce correct code, what's hard is to make it produce correct code that runs faster than simply leaving short & char variables in memory (since if you use registers and get no real speed advantage, then you are losing the possibility of putting other variables that would give some benefit in a register). What follows is a test for correctness of C compilers in this area. It is a shell archive, cut on the dotted line, and extract with sh (not csh). Then read the README file carefully. Then type "make". Make takes less than a minute on an unloaded 780 running 4.2bsd. When it finishes, you might know that your compiler is broken. If you don't know that, then you have wasted your time, since nothing here will demonstrate that your compiler is not broken. If your compiler implements "register" types, and doesn't fail this test, then you should probably look at the assembler code produced, and see if the code to process the register variable is any better than the code produced to process the non register variable. Note: This code is intended to run on any system with a C compiler that supports printf. However, this has not been tested and I guarantee nothing. The makefile will only work on systems with make of course, but you should be able to guess what it is doing easily enough, and emulate "make" by hand, or with some kind of command script if your system has no "make". If you don't have printf, then the basic code should still work, you will just need to change the way the diagnostics are produced. If you have a compiler with a broken, or no, preprocessor, then you may need to edit the source for each test. Robert Elz seismo!munnari!kre kre%munnari.oz@seismo.css.gov : ---------------------------------------- cut here echo x - "README" 2>&1 sed "s/^X//" >"README" <<'!The!End!' XThis is a simple test for one possible bug in implementations of C. X XSimply extract this shar archive (maybe you have done that already) Xand type "make". If all is OK, you will see several "Testing" Xlines printed to stdout. If there are problems, lines containing Xthe word "Fails" will appear. X XNote: the existence of any "Fails" lines in the output implies Xthat your implementation of C is deficient. The converse is not Xtrue. Absence of "Fails" lines says nothing at all about anything. XOn a cpu with 8 bit chars, and 16 bit shorts, absence of any X"Fails" lines probably suggests that the compiler is OK in this Xrespect. Other cpu architectures may need the initialization of Xthe "values" array extended. You can put any numbers in that that Xyou like (and which allow the source to compile). There is no such Xthing as "bad data" here, for any number that you can think of to put Xin that array, the tests in the code should never fail. X XVERY IMPORTANT NOTE: Please, if you run this test, DO NOT report Xyour findings to the net. No-one (except you) cares if your compiler Xworks or not. If you have a broken compiler, complain to whoever Xsupplied it. X XRobert Elz seismo!munnari!kre kre%munnari.oz@seismo.css.gov !The!End! echo x - "Makefile" 2>&1 sed "s/^X//" >"Makefile" <<'!The!End!' X# X# C compiler "register type" test X# X XOPT= -O X Xtest: X @-for type in short char int unsigned long "unsigned short" \ X "unsigned char" ;\ X do \ X cc $(OPT) -o cctst -Dtype="$$type" cctst.c ;\ X echo "Testing $$type" ;\ X ./cctst ;\ X done X Xclean: X rm -f cctst core a.out *.o *junk* *[Ee]rr* *[Mm]ade* !The!End! echo x - "cctst.c" 2>&1 sed "s/^X//" >"cctst.c" <<'!The!End!' X/* X * The numbers in this array are test cases that will (hopefully) X * find faults on processors with 8 bit char variables, and 16 bit X * short variables. Other processor types should add new values. X * Any number that fits is OK, if you can find *any* value that X * fails, you have a broken compiler. X */ Xlong values[] = { X 0, X -1, X (1 << 15), X (1 << 16) - 1, X (1 << 15) + 1, X (1 << 15) - 1, X ~0, X (1 << 7), X (1 << 8) - 1, X (1 << 7) + 1, X (1 << 7) - 1, X (1 << 31), X (1 << 31) + 1, X (1 << 31) - 1, X (1 << 32) - 1, X}; X X#ifndef type X#define type short X#endif X Xmain() X{ X register type rtype; X auto type atype; X register long *vp; X X for (vp = values; vp < &values[sizeof values/sizeof values[0]]; vp++) { X rtype = *vp; X atype = *vp; X X if (rtype != atype) X printf("Fails simple assignment for %d\n", *vp); X X if (++rtype != ++atype) X printf("Fails ++ equality for %d\n", *vp); X X if (rtype != atype) X printf("Fails incremented assignment for %d\n", *vp); X X rtype = *vp; X atype = *vp; X X if (--rtype != --atype) X printf("Fails -- equality for %d\n", *vp); X X if (rtype != atype) X printf("Fails decremented assignment for %d\n", *vp); X } X exit(0); X} !The!End! exit