lew@dgbt.uucp (Lew Stelmach) (04/11/89)
The following program compiles successfully on Microsoft C5.1, Microsoft Quick C 2.0, TurboC, DEC VAX Ultrix C, Sun Unix C, and other compilers. However, it does not run correctly when compiled using Microsoft C5.1. Note that it runs correctly on Microsoft Quick C 2.0. The program allocates a ring of pointers. The correct form of the output is shown below the program listing. The actual values will differ from machine to machine . The pattern is what matters. The critical feature to look for is that the right-most column of addresses (pointer values) should increase if the program runs correctly. In MSC5.1 these numbers stay constant. I compiled with the medium memory (cl -AM). /*-------------------------------------------------*/ #include <stdio.h> struct Block{ struct Block *fwp; }; main () { struct Block *at,*aa; char *c; int i; at=NULL; for(i=0;i<10;i++){ aa=(struct Block *)malloc(sizeof(struct Block)); if(!aa)break; if(at){ aa->fwp=at->fwp; at->fwp=aa; } else { at=aa; aa->fwp=aa; } printf("at=%d aa=%d at->fwp=%d aa->fwp=%d\n", at,aa,at->fwp,aa->fwp); } } /* --------------------------------------------------*/ Sample output (correct version). In the incorrect (MSC5.1) version the rightmost column would be 5124 all the way down. at=5124 aa=5124 at->fwp=5124 aa->fwp=5124 at=5124 aa=5132 at->fwp=5132 aa->fwp=5124 at=5124 aa=5140 at->fwp=5140 aa->fwp=5132 at=5124 aa=5148 at->fwp=5148 aa->fwp=5140 at=5124 aa=5156 at->fwp=5156 aa->fwp=5148 at=5124 aa=5164 at->fwp=5164 aa->fwp=5156 at=5124 aa=5172 at->fwp=5172 aa->fwp=5164 at=5124 aa=5180 at->fwp=5180 aa->fwp=5172 at=5124 aa=5188 at->fwp=5188 aa->fwp=5180 at=5124 aa=5196 at->fwp=5196 aa->fwp=5188 Do you have an explanation or any comments? Lew Stelmach --------------------------------------------------------------------- Lew Stelmach, Ph.D. Communications Research Centre P.O. Box 11490, Station H (613) 998 2005 Ottawa, Ontario, K2H 8S2, Canada BITNET: lew@doccrc.bitnet Others: lew@dgbt.crc.dnd.ca ---------------------------------------------------------------------
wilson@uhccux.uhcc.hawaii.edu (Tom Wilson) (04/14/89)
In article <1051@dgbt.uucp> lew@dgbt.crc.dnd.ca (Lew Stelmach) writes: >The following program compiles successfully on Microsoft C5.1, >Microsoft Quick C 2.0, TurboC, DEC VAX Ultrix C, Sun Unix C, and other >compilers. However, it does not run correctly when compiled using >Microsoft C5.1. Note that it runs correctly on Microsoft Quick C 2.0. > [ Program listing and output deleted] 1. I ran this and confirm the bug in MSC 5.1 2. When I specified no compiler optimzation (/Od), the bug went away. While I don't have time to look at the object output, it looks like maybe some incorrect overoptimization. 3. This isn't the first MSC bug that I have seen posted, or found myself. While I have seen postings from various folks at Microsoft, I have never found a direct e-mail route for sending this type of bug. They seem to want everything to come by U.S. Snail. Is this actually the case? What about other vendors (not just PCs) -- this would seem like a useful group for someone at the compiler builders to watch; it doesn't seem like it would take that much time (just judicious use of 'k'). >Lew Stelmach, Ph.D. Communications Research Centre > P.O. Box 11490, Station H >(613) 998 2005 Ottawa, Ontario, K2H 8S2, Canada > >BITNET: lew@doccrc.bitnet >Others: lew@dgbt.crc.dnd.ca >--------------------------------------------------------------------- -- Tom Wilson wilson@uhccux.uhcc.Hawaii.Edu (Internet) wilson@uhccux.UUCP || wilson@uhccux (Bitnet)
austing@Apple.COM (Glenn L. Austin) (04/14/89)
In article <1051@dgbt.uucp> lew@dgbt.crc.dnd.ca (Lew Stelmach) writes: >The following program compiles successfully on Microsoft C5.1, >Microsoft Quick C 2.0, TurboC, DEC VAX Ultrix C, Sun Unix C, and other >compilers. However, it does not run correctly when compiled using >Microsoft C5.1. Note that it runs correctly on Microsoft Quick C 2.0. > >The program allocates a ring of pointers. The correct form of the >output is shown below the program listing. The actual values will >differ from machine to machine . The pattern is what matters. The >critical feature to look for is that the right-most column of addresses >(pointer values) should increase if the program runs correctly. In >MSC5.1 these numbers stay constant. I compiled with the medium memory > > [Example deleted] > I found that anytime I used 32-bit pointers in MSC5.1, the code would compile correctly, but that the segment values would not be assigned correctly from pointer to pointer. The symptoms I encountered were random crashes, not from my code, but from interrupts. Putting the code through an I2ICE (what a nice debugging tool!) showed that even though the segment was set correctly on my first pointer (from malloc), re-assigning it later to another pointer caused the segment to always be set to 0. The only solution I (and MS) found was to move the segment and offset separately. ----------------------------------------------------------------------------- | Glenn L. Austin | The nice thing about standards is that | | Apple Computer, Inc. | there are so many of them to choose from. | | Internet: austing@apple.com | -Andrew S. Tanenbaum | ----------------------------------------------------------------------------- | All opinions stated above are mine -- who else would want them? | -----------------------------------------------------------------------------
afscian@violet.waterloo.edu (Anthony Scian) (04/15/89)
In article <3758@uhccux.uhcc.hawaii.edu> wilson@uhccux.UUCP (Tom Wilson) writes: >In article <1051@dgbt.uucp> lew@dgbt.crc.dnd.ca (Lew Stelmach) writes: >>The following program compiles successfully on Microsoft C5.1, >>Microsoft Quick C 2.0, TurboC, DEC VAX Ultrix C, Sun Unix C, and other >>compilers. However, it does not run correctly when compiled using >>Microsoft C5.1. Note that it runs correctly on Microsoft Quick C 2.0. >[ Program listing and output deleted] >1. I ran this and confirm the bug in MSC 5.1 >2. When I specified no compiler optimzation (/Od), the bug went away. While > I don't have time to look at the object output, it looks like maybe some > incorrect overoptimization. The problem is probably in the -Oa (ignore aliasing) optimization. The 'ignore aliasing' optimzation will assume that any indirection will not invalidate any other value that may be stored in registers or temporaries. The 'ignore aliasing' optimization is a dangerous optimization to perform especially in the 'anything goes' form that Microsoft uses. (Turbo C has the same problem in certain cases) Basically, -Ox is unusable because -Ox turns on this optimization. The 'loop optimzations' switch -Ol is also dangerous because it can break working programs (although at a lesser rate). //// Anthony Scian afscian@violet.uwaterloo.ca afscian@violet.waterloo.edu //// "I can't believe the news today, I can't close my eyes and make it go away" -U2
kremer@cs.odu.edu (Lloyd Kremer) (04/15/89)
In article <28956@apple.Apple.COM> austing@Apple.COM (Glenn L. Austin) writes: >I found that anytime I used 32-bit pointers in MSC5.1, the code would compile >correctly, but that the segment values would not be assigned correctly from >pointer to pointer. The symptoms I encountered were random crashes, not from >my code, but from interrupts. Putting the code through an I2ICE (what a nice >debugging tool!) showed that even though the segment was set correctly on my >first pointer (from malloc), re-assigning it later to another pointer caused >the segment to always be set to 0. The only solution I (and MS) found was to >move the segment and offset separately. I too have had problems with 4-byte pointers apparently "forgetting" their segment values when using MSC 5.1, but in my experience the pointers would magically acquire the default data segment (register DS), rather than segment 0. I was compiling under large model, where both code and data pointers are 4 bytes by default (unless the 'near' keyword is used). In one section of code, comparisons through pointers were not working, since half the objects being compared were in a far data segment, and the compiled code was apparently assuming that all were in the default segment. The pointers happened to be char *'s. I found that the stopgap solution was to include an explicit cast to 'char far *' at every pointer reference within the troublesome code section. I felt somewhat miffed at having to keep "reminding" the compiler that it was in large model. In light of a previous posting on this subject, it appears that the problem was not so much in "forgetting" to carry the pointer segment during code generation, but in losing it in subsequent overzealous optimizing. I concluded that the only reason the vast majority of large model code works is that although each function is in a different segment, the data are usually all kept in the default data segment. I had a few large objects that had been farmed out to far data segments, so my code broke. Lloyd Kremer Brooks Financial Systems {uunet,sun,...}!xanth!brooks!lloyd