ID Number: Q61310
5.10 6.00 | 5.10 6.00
MS-DOS | OS/2
buglist5.10 buglist6.00 fixlist6.00a
Summary:
The Microsoft C Compiler versions 5.1 and 6.0 may generate incorrect
code for nested conditionals with /Ot in large or compact memory model
if the the conditionals are the same expression.
More Information:
The sample code below demonstrates the problem, as shown by this
program output:
Actual Expected
------ --------
1 0
2 1
3 2
4 3
4
The following workarounds may be used to eliminate the error:
1. Change "i < 5" in the for loop or if statement to "i <= 4".
2. Use -Od to disable optimization when compiling.
3. Use the #pragma optimization ("t", off/on) statement to
disable/enable the default -Ot optimization before and after the
function.
4. Use a combination of optimizations (for example, -Ox, -Olt, and so
forth).
The problem is with the default -Ot optimization; in particular, when
used by itself, the optimizer will generate incorrect code.
In the code sample, the compiler does not generate the instruction for
the first comparison in the for loop (as shown below). This causes the
instruction pointer to jump to location $FC176 the first time through
the loop. The end result is the same as if "i" went from 1 to 4
instead of from 0 to 4.
.
.
mov WORD PTR [bp-2], 0
$F166:
cmp WORD PTR [bp-2], 5 ;<- This "cmp" is missing
jge $FC167
push WORD PTR [bp-2]
mov ax, OFFSET DGROUP:$SG170
push ax
call _printf
add sp,4
$FC176:
inc WORD PTR [bp-2]
cmp WORD PTR [bp-2], 5
jl $F166
.
.
Microsoft has confirmed this to be a problem in C versions 5.1 and
6.0. This problem was corrected in C version 6.0a.
Sample Code
-----------
/* Compile options needed: /AL /Ot
*/
#include <stdio.h>
void main (void)
{
int i;
for ( i = 0; i < 5; i++)
if (i < 5)
printf ("%d\n", i);
}