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