C 5.1 /Oa May Cause Changes in Variable Values to Be Ignored

ID Number: Q43912

5.10 | 5.10

MS-DOS | OS/2

buglist5.10 fixlist6.00

Summary:

The Microsoft C Compiler version 5.1 generates incorrect code for the

sample program below when it is compiled with /Oa (assume no

aliasing). Two work around the problem, compile without /Oa or use a

temporary variable.

Microsoft has confirmed this to be a problem in C version 5.1. This

problem was corrected in C version 6.0.

Sample Code

-----------

/* Compile options needed: /Oa

*/

static int index;

static int len;

static char *strbuf;

void main()

{

if (index >= len)

{

strbuf[len++] = ' '; /* works correctly */

strbuf[len] = '\0'; /* null is put in the wrong place! */

}

}

Assembly Listing

----------------

_main:

7: {

5C83:0000 56 PUSH SI

8: if (index >= len)

5C83:0001 A1DE01 MOV AX,Word Ptr [len (01DE)]

5C83:0004 3906DA01 CMP Word Ptr [index (01DA)],AX

5C83:0008 7C13 JL _main+1d (001D)

10: strbuf[len++] = ' '; /* works correctly */

5C83:000A BEDE01 MOV SI,len (01DE)

5C83:000D 8B1C MOV BX,Word Ptr [SI]

5C83:000F FF04 INC Word Ptr [SI]

5C83:0011 8B36DC01 MOV SI,Word Ptr [strbuf (01DC)]

5C83:0015 C60020 MOV Byte Ptr [BX+SI],20

11: strbuf[len] = '\0'; /* null is put in the wrong place */

5C83:0018 8BD8 MOV BX,AX

5C83:001A C60000 MOV Byte Ptr [BX+SI],00

13: }

5C83:001D 5E POP SI

The "MOV BX, AX" generated for "strbuf[len] = '\0';" above should be a

"MOV BX, [len]". AX contains the old value of len at this point, not

the incremented value.