C compiler bug
ae504pw at prism.gatech.edu
ae504pw at prism.gatech.edu
Sat Jul 14 05:53:16 AEST 1990
Greetings,
I believe I may have found a bug in the C compiler on the Iris. I compiled the
following program, taken from the April 1985 PC Tech Journal,
-----------------------Cut Here----------------------------------------
/*---------------------------------------------------------*/
/* High Performance CRC Computation Routine */
/* */
/* Copyright 1985 W. David Schwaderer */
/* All rights reserved */
/* */
/* Compiler used: Computer Innovations C86 V2.10A */
/* */
/* Warning...this program uses bit fields! */
/* For warnings on bit field hazards see: */
/* */
/* The C Wizard's Programming Reference Handbook */
/* W. David Schwaderer */
/* John Wiley and Sons, 1985 */
/* */
/*---------------------------------------------------------*/
/* Watch bit fields...see my C book... */
#include <stdio.h>
#define VOID int
unsigned crc_table[256]; /* globally accessible */
main(argc, argv)
int argc;
char *argv[];
{
VOID GenerateTable();
unsigned GenerateCRC();
unsigned length, crc;
/* crc = 0x9001 */
static char TestArray1[] = {'\001', '\000'};
static char TestArray2[] = {'\001','\000', '\001', '\220'};
/* bytewise bytewise */
/* unreversed reversed */
static char TestMsg[] = "This is a test message.";
GenerateTable(); /* fill in the crc_table */
PrintTable(); /* display the table */
length = sizeof(TestArray1);
crc = GenerateCRC(length, TestArray1); /* calculate CRC */
printf("\n\n\nTestArray1 CRC = 0x%04x", crc);
length = sizeof(TestArray2);
crc = GenerateCRC(length, TestArray2); /* calculate CRC */
printf("\n\n\nTestArray2 CRC = 0x%04x", crc);
length = sizeof(TestMsg) - 1; /* avoid terminating NUL */
crc = GenerateCRC(length, TestMsg); /* calculate a CRC */
printf("\n\n\nText = [%s]\nCRC = %04x\n\n", TestMsg, crc);
return(0);
}
VOID GenerateTable() /* generate the look-up table */
{
int temp;
union { int i;
struct {
unsigned i1 :1; /* low order bit */
unsigned i2 :1;
unsigned i3 :1;
unsigned i4 :1;
unsigned i5 :1;
unsigned i6 :1;
unsigned i7 :1;
unsigned i8 :1; /* high order bit */
unsigned :24; /* unused */
} Bit;
} iUn;
union { unsigned int Entry;
struct {
unsigned b1 :1; /* low order bit */
unsigned b2 :1;
unsigned b3 :1;
unsigned b4 :1;
unsigned b5 :1;
unsigned b6 :1;
unsigned b7 :1;
unsigned b8 :1;
unsigned b9 :1;
unsigned b10 :1;
unsigned b11 :1;
unsigned b12 :1;
unsigned b13 :1;
unsigned b14 :1;
unsigned b15 :1;
unsigned b16 :1; /* high order bit */
unsigned :16; /* unused */
} EntryBit;
} EntryUn;
for (iUn.i = 0; iUn.i < 256; iUn.i++) {
EntryUn.Entry = 0; /* bits 2 thru 6 zeroed out now */
temp = (iUn.Bit.i7 ^ iUn.Bit.i6 ^ iUn.Bit.i5 ^
iUn.Bit.i4 ^ iUn.Bit.i3 ^ iUn.Bit.i2 ^
iUn.Bit.i1);
EntryUn.EntryBit.b16 = (iUn.Bit.i8 ^ temp);
EntryUn.EntryBit.b15 = (temp);
EntryUn.EntryBit.b14 = (iUn.Bit.i8 ^ iUn.Bit.i7);
EntryUn.EntryBit.b13 = (iUn.Bit.i7 ^ iUn.Bit.i6);
EntryUn.EntryBit.b12 = (iUn.Bit.i6 ^ iUn.Bit.i5);
EntryUn.EntryBit.b11 = (iUn.Bit.i5 ^ iUn.Bit.i4);
EntryUn.EntryBit.b10 = (iUn.Bit.i4 ^ iUn.Bit.i3);
EntryUn.EntryBit.b9 = (iUn.Bit.i3 ^ iUn.Bit.i2);
EntryUn.EntryBit.b8 = (iUn.Bit.i2 ^ iUn.Bit.i1);
EntryUn.EntryBit.b7 = (iUn.Bit.i1);
EntryUn.EntryBit.b1 = (iUn.Bit.i8 ^ temp);
crc_table[iUn.i] = EntryUn.Entry;
}
}
VOID PrintTable() /* print out the look-up table */
{
int i;
for (i=0; i < 256; i++) {
if ( !(i % 8) )
printf("\n %02x - %04x", i, crc_table[i]);
else
printf(" %04x", crc_table[i]);
}
}
unsigned GenerateCRC(Length, TextPtr)
unsigned Length;
char *TextPtr;
{
int i, index;
unsigned crc;
crc = 0; /* crc starts at zero for each message */
for (i = 0; i < Length; i++, TextPtr++) {
index = ( (crc ^ *TextPtr) & 0x00FF);
crc = ( (crc >> 8) & 0x00FF) ^ crc_table[index];
}
return(crc);
}
--------------------Cut Here-----------------------------------
and ran it, giving me the following output:
00 - 0000 0000 0000 0000 0000 0000 0000 0000
08 - 0000 0000 0000 0000 0000 0000 0000 0000
10 - 0000 0000 0000 0000 0000 0000 0000 0000
18 - 0000 0000 0000 0000 0000 0000 0000 0000
20 - 0000 0000 0000 0000 0000 0000 0000 0000
28 - 0000 0000 0000 0000 0000 0000 0000 0000
30 - 0000 0000 0000 0000 0000 0000 0000 0000
38 - 0000 0000 0000 0000 0000 0000 0000 0000
40 - 0000 0000 0000 0000 0000 0000 0000 0000
48 - 0000 0000 0000 0000 0000 0000 0000 0000
50 - 0000 0000 0000 0000 0000 0000 0000 0000
58 - 0000 0000 0000 0000 0000 0000 0000 0000
60 - 0000 0000 0000 0000 0000 0000 0000 0000
68 - 0000 0000 0000 0000 0000 0000 0000 0000
70 - 0000 0000 0000 0000 0000 0000 0000 0000
78 - 0000 0000 0000 0000 0000 0000 0000 0000
80 - 0000 0000 0000 0000 0000 0000 0000 0000
88 - 0000 0000 0000 0000 0000 0000 0000 0000
90 - 0000 0000 0000 0000 0000 0000 0000 0000
98 - 0000 0000 0000 0000 0000 0000 0000 0000
a0 - 0000 0000 0000 0000 0000 0000 0000 0000
a8 - 0000 0000 0000 0000 0000 0000 0000 0000
b0 - 0000 0000 0000 0000 0000 0000 0000 0000
b8 - 0000 0000 0000 0000 0000 0000 0000 0000
c0 - 0000 0000 0000 0000 0000 0000 0000 0000
c8 - 0000 0000 0000 0000 0000 0000 0000 0000
d0 - 0000 0000 0000 0000 0000 0000 0000 0000
d8 - 0000 0000 0000 0000 0000 0000 0000 0000
e0 - 0000 0000 0000 0000 0000 0000 0000 0000
e8 - 0000 0000 0000 0000 0000 0000 0000 0000
f0 - 0000 0000 0000 0000 0000 0000 0000 0000
f8 - 0000 0000 0000 0000 0000 0000 0000 0000
TestArray1 CRC = 0x0000
TestArray2 CRC = 0x0000
Text = [This is a test message.]
CRC = 0000
Something is definitely amiss here! On a whim I compiled and ran the identical
code on a Sequent S81. The results in that case are quite different as seen
below.
00 - 0000 c0c1 c181 0140 c301 03c0 0280 c241
08 - c601 06c0 0780 c741 0500 c5c1 c481 0440
10 - cc01 0cc0 0d80 cd41 0f00 cfc1 ce81 0e40
18 - 0a00 cac1 cb81 0b40 c901 09c0 0880 c841
20 - d801 18c0 1980 d941 1b00 dbc1 da81 1a40
28 - 1e00 dec1 df81 1f40 dd01 1dc0 1c80 dc41
30 - 1400 d4c1 d581 1540 d701 17c0 1680 d641
38 - d201 12c0 1380 d341 1100 d1c1 d081 1040
40 - f001 30c0 3180 f141 3300 f3c1 f281 3240
48 - 3600 f6c1 f781 3740 f501 35c0 3480 f441
50 - 3c00 fcc1 fd81 3d40 ff01 3fc0 3e80 fe41
58 - fa01 3ac0 3b80 fb41 3900 f9c1 f881 3840
60 - 2800 e8c1 e981 2940 eb01 2bc0 2a80 ea41
68 - ee01 2ec0 2f80 ef41 2d00 edc1 ec81 2c40
70 - e401 24c0 2580 e541 2700 e7c1 e681 2640
78 - 2200 e2c1 e381 2340 e101 21c0 2080 e041
80 - a001 60c0 6180 a141 6300 a3c1 a281 6240
88 - 6600 a6c1 a781 6740 a501 65c0 6480 a441
90 - 6c00 acc1 ad81 6d40 af01 6fc0 6e80 ae41
98 - aa01 6ac0 6b80 ab41 6900 a9c1 a881 6840
a0 - 7800 b8c1 b981 7940 bb01 7bc0 7a80 ba41
a8 - be01 7ec0 7f80 bf41 7d00 bdc1 bc81 7c40
b0 - b401 74c0 7580 b541 7700 b7c1 b681 7640
b8 - 7200 b2c1 b381 7340 b101 71c0 7080 b041
c0 - 5000 90c1 9181 5140 9301 53c0 5280 9241
c8 - 9601 56c0 5780 9741 5500 95c1 9481 5440
d0 - 9c01 5cc0 5d80 9d41 5f00 9fc1 9e81 5e40
d8 - 5a00 9ac1 9b81 5b40 9901 59c0 5880 9841
e0 - 8801 48c0 4980 8941 4b00 8bc1 8a81 4a40
e8 - 4e00 8ec1 8f81 4f40 8d01 4dc0 4c80 8c41
f0 - 4400 84c1 8581 4540 8701 47c0 4680 8641
f8 - 8201 42c0 4380 8341 4100 81c1 8081 4040
TestArray1 CRC = 0x9001
TestArray2 CRC = 0x0000
Text = [This is a test message.]
CRC = 9d6a
This is the correct output. What gives? Is there a bug in the Irix C compiler
or is there some caveat with bit fields, which this program uses, that I am
not aware of? I am a relative newcomer to C and typed this program in as an
example of one which uses bit fields. The manual reveals little about bit
fields other than that they must fit into a word.
Hardware specifics: Iris 4D/120GTX running Irix 3.2
Sequent S81 running DYNIX V3.0.17.9
Any tips or insight would be greatly appreciated.
--
John Forrest
Georgia Institute of Technology, Atlanta Georgia, 30332
uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!ae504pw
Internet: ae504pw at prism.gatech.edu
More information about the Comp.sys.sgi
mailing list