[comp.lang.c] Microsoft C 5.1 - bug

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