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.