[comp.sys.sgi] C compiler bug

ae504pw@prism.gatech.edu (07/14/90)

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@prism.gatech.edu

mark@mips.COM (Mark G. Johnson) (07/15/90)

In article <9007131953.AA08463@prism> ae504pw@prism.gatech.edu writes:
  >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 ...
  >
  > [code for "High Performance CRC Computation Routine" removed]
  >
  >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.
  >

Lint found little to complain about, so I tried the experiment of
compiling and running the program on a Sun SPARCstation 1, an
Apollo DN4000, and a MIPS RC3240.  All three of these produced the same
output as the IRIS.  So the scorecard thus far is:


    Printed the result                  Printed the result that
   John Forrest wanted                  John Forrest didn't want
---------------------------------------------------------------------------
  Sequent  S81  DYNIX V3.0.17.9      SGI   Iris 4D/120GTX   Irix 3.2
                                     Sun   SPARCstation 1   SunOs 4.0.3c
                                     MIPS  RC3240           RISC/os 4.50
                                     Apollo DN4000          BSD 4.2 DOMAIN-IX

The "wrong answer" machines contain 4 different CPUs (R2000, Cy7C601,
R3000, 68020) and employ 3 different C compilers.

Here is the output from the SPARCstation 1.  "diff" says it is identical to
the DN4000 and the RC3240 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
-- 
 -- Mark Johnson	
 	MIPS Computer Systems, 930 E. Arques M/S 2-02, Sunnyvale, CA 94086
	(408) 524-8308    mark@mips.com  {or ...!decwrl!mips!mark}

krk@cs.purdue.EDU (Kevin Kuehl) (07/15/90)

In article <40159@mips.mips.COM> mark@mips.COM (Mark G. Johnson) writes:
>  Sequent  S81  DYNIX V3.0.17.9      SGI   Iris 4D/120GTX   Irix 3.2
>                                     Sun   SPARCstation 1   SunOs 4.0.3c
>                                     MIPS  RC3240           RISC/os 4.50
>                                     Apollo DN4000          BSD 4.2 DOMAIN-IX

I would go with the non-Sequent machines here also.  Our Symmetries
sometimes generate really strange code.  We have traced apparent bugs
in software to flags given the C compiler.  Compile the software with
one flag and it dumps core, compile it with another and the program
runs just fine.

Kevin
krk@cs.purdue.edu
...!{gatech,ucbvax,uunet}!purdue!krk

kai@sp1.csrd.uiuc.edu (Kuck And Associates) (07/18/90)

mark@mips.COM (Mark G. Johnson) writes:

>The "wrong answer" machines contain 4 different CPUs (R2000, Cy7C601,
>R3000, 68020) and employ 3 different C compilers.

It appears the "wrong answer" machines are all Big Endian (bytes are stored in
memory in the order 4321, as opposed to the S81's i386 processors, which are
Little Endian).  Perhaps the code isn't quite portable.

Patrick Wolfe   (pat@kai.com, kailand!pat)
System Programmer/Operations Manager, Kuck & Associates
"Any opinions expressed are my own, not my employers's.
 Please don't call my boss and complain ... again."

kai@sp1.csrd.uiuc.edu (Kuck And Associates) (07/18/90)

kai@sp1.csrd.uiuc.edu (Kuck And Associates) writes:
>It appears the "wrong answer" machines are all Big Endian (bytes are stored in
>memory in the order 4321, as opposed to the S81's i386 processors, which are
>Little Endian).  Perhaps the code isn't quite portable.

I was right.  Compile the following fixed version of that pgm defining
BIG_ENDIAN on hosts running 680x0's, MIPS processors, and you get the exact
same results as on Little Endian machines, like your Sequent S81.  The
program's author DOES warn to "Watch bit fields...see my C book...".

	Patrick Wolfe   (pat@kai.com, kailand!pat)
	System Programmer/Operations Manager, Kuck & Associates
	"Any opinions expressed are my own, not my employers's.
	 Please don't call my boss and complain ... again."

--  cut here  --  cut here  --  cut here  --  cut here  --  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 {
#ifdef BIG_ENDIAN
           unsigned     :24; /* bytes 4, 3 and 2 */
           unsigned i8  :1; /* byte 1 */
           unsigned i7  :1;
           unsigned i6  :1;
           unsigned i5  :1;
           unsigned i4  :1;
           unsigned i3  :1;
           unsigned i2  :1;
           unsigned i1  :1;
#else  /* ! BIG_ENDIAN */
           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         */
#endif /* BIG_ENDIAN */
           } Bit;
       } iUn;

   union {  unsigned int  Entry;
       struct {
#ifdef BIG_ENDIAN
	   unsigned     :16; /* bytes 4 and 3 */
           unsigned b16 :1;
           unsigned b15 :1;
           unsigned b14 :1;
           unsigned b13 :1;
           unsigned b12 :1;
           unsigned b11 :1;
           unsigned b10	:1;
           unsigned b9  :1; /* byte 2 */
           unsigned b8  :1; /* byte 1 */
           unsigned b7  :1;
           unsigned b6  :1;
           unsigned b5  :1;
           unsigned b4  :1;
           unsigned b3  :1;
           unsigned b2  :1;
           unsigned b1  :1;
#else	/* ! BIG_ENDIAN */
           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 */
#endif /* BIG_ENDIAN */
	} 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);

}

mg@GODZILLA.CGL.RMIT.OZ.AU (Mike Gigante) (05/03/91)

In the following code:

void
  drawbbox(struct bbox bb)
{
  float v[7][3];
  int i;

  /*
   * a close enough approximation...
   */
  v[0][0] = bb.x1;
  v[0][1] = bb.y1;
  v[0][2] = bb.z1;

  v[1][0] = bb.x2;
  v[1][1] = bb.y1;
  v[1][2] = bb.z1;

  v[2][0] = bb.x2;
  v[2][1] = bb.y2;
  v[2][2] = bb.z1;

  v[3][0] = bb.x1;
  v[3][1] = bb.y2;
  v[3][2] = bb.z1;

  v[4][0] = bb.x1;
  v[4][1] = bb.y2;
  v[4][2] = bb.z2;

  v[5][0] = bb.x2;
  v[5][1] = bb.y2;
  v[5][2] = bb.z2;

  v[6][0] = bb.x2;
  v[6][1] = bb.y1;
  v[6][2] = bb.z2;  (*)

  v[7][0] = bb.x1;
  v[7][1] = bb.y1;
  v[7][2] = bb.z2;  (**)

  bgnclosedline();
  for(i=0; i < 8; i++)
    v3f(v[i]);
  endclosedline();
}

I get an incorrectly draw bbox. Ok, so I did the following:


  bgnclosedline();
  for(i=0; i < 8; i++) {
    v3f(v[i]);
    printf("bbox: %f %f %f\n", v[i][0], v[i][1], v[i][2]);
  }
  endclosedline();

and lo and behold, it tells me that the Z value for the last point is
wrong while for the second last point, it is correct. A quick look at
the assignment code shows that in both positions, (see * & **), reveals
that this should *not* happen.

The cure was to declare v to be 

	volatile v[8][3];

and change the v3f call to

	v3f((float *)v[i]);

An alternative solution is to use -O0, but that doesn't appeal for other
reasons :-)

Mike Gigante,
ACGC
Royal Melbourne Institute of Technology

mg@GODZILLA.CGL.RMIT.OZ.AU (Mike Gigante) (05/03/91)

whoops, I made a typo -- the line

	volatile v[8][3];

 which I indicated was the fix, actually is

	volatile float v[][];

thanks!

Mike Gigante, mg@godzilla.cgl.rmit.oz.au

meuer@cs.umn.edu (Mark V. Meuer) (05/03/91)

In <9105021249.16330@godzilla.cgl.rmit.oz.au> mg@GODZILLA.CGL.RMIT.OZ.AU (Mike Gigante) writes:


>In the following code:

>void
>  drawbbox(struct bbox bb)
>{
>  float v[7][3];
>  int i;

>  /*
>   * a close enough approximation...
>   */
...
[stuff deleted to save bandwidth]
...
>  v[7][0] = bb.x1;
>  v[7][1] = bb.y1;
>  v[7][2] = bb.z2;  (**)

>  bgnclosedline();
>  for(i=0; i < 8; i++)
>    v3f(v[i]);
>  endclosedline();
>}

>I get an incorrectly draw bbox. 

From the looks of it, you should get a segmentation fault.  You are
declaring v to have 7 elements, yet you are filling it with eight
(0-7). 

> Ok, so I did the following:


>  bgnclosedline();
>  for(i=0; i < 8; i++) {
>    v3f(v[i]);
>    printf("bbox: %f %f %f\n", v[i][0], v[i][1], v[i][2]);
>  }
>  endclosedline();

>and lo and behold, it tells me that the Z value for the last point is
>wrong while for the second last point, it is correct. A quick look at
>the assignment code shows that in both positions, (see * & **), reveals
>that this should *not* happen.

Ah, but since the last point is beyond the declared end of the array,
it is not defined what will happen.  Except, of course, that whatever
will happen will be bad.



>Mike Gigante,
>ACGC
>Royal Melbourne Institute of Technology


-mark
-- 
Mark Meuer   <><    |  The Geometry Center  |  meuer@geom.umn.edu
"My guess is that object-oriented programming will be in the 1980's what
structured programming was in the 1970's.  Everyone will be in favor of it.
Every manager will pay lip service to it.  Every programmer will practice it