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