FIX: Loop Optimization Causes Infinite Do-While Loop

ID: Q115704


The information in this article applies to:
  • The C/C++ Compiler (CL.EXE), included with:
    • Microsoft C for MS-DOS, versions 6.0, 6.0a, 6.0ax
    • Microsoft C for OS/2, versions 6.0, 6.0a
    • Microsoft C/C++ for MS-DOS, version 7.0
    • Microsoft Visual C++ for Windows, versions 1.0, 1.5
    • Microsoft Visual C++ 32-bit Edition, version 1.0


SYMPTOMS

The use of loop optimization (/Ol, or /Ox for the C/C++ compiler 8.0 for Windows NT) in a do-while loop that terminates after a single iteration may cause an infinite loop. The code below can be used to demonstrate this behavior. An infinite loop is generated when the expression (i <= e) from the program below is true during the first loop iteration.


CAUSE

Examining the assembly/source code file generated by using the /Fc compiler option reveals that the comparison operation differs with the optimized and non-optimized versions. The optimized version will only reenter the loop if the two values are not equal, whereas the non-optimized version correctly checks if i is less than or equal to e.

Optimized version:


;|***   while (i<=e);
; Line 17
    *** 000059 ff 4e f4           dec WORD PTR [bp-12]
    *** 00005c 75 f1              jne $D536

Non-optimized version:

;|***   while (i<=e);
; Line 17
  L00537:
    *** 000054 8b 46 f6           mov ax,WORD PTR -10[bp]
    *** 000057 39 46 fc           cmp WORD PTR -4[bp],ax
    *** 00005a 7f 03 e9 e7 ff     jle L00536 


RESOLUTION

There are two workarounds to this problem:

  1. Use the fast compiler option /f.


  2. -or-

  3. Disable optimization during the function where the infinite loop occurs by using the optimize pragma:
    
          #pragma optimize("",off)
    
          void bad_loop_function(void)
          {
          /* ... */ 
          }
    
          #pragma optimize("",on) 



STATUS

Microsoft has confirmed this to be a bug in the products listed at the beginning of this article. This problem was corrected in the C/C++ compiler version 9.0, included with Visual C++ 32-bit Edition, version 2.0.


MORE INFORMATION

The following sample code can be used to demonstrate the problem.

Sample Code


/* Compile options needed: /Ol
*/ 

#include <stdio.h>

void main(void)
{
   int a, b, c;
   int e, i;

   scanf("%d%d%d", &a, &b, &c);
   printf("%d%d%d", a, b, c);

   i=a-c;
   e=b-c;
   do
   {
      printf("x");
      i++;
   }
   while (i<=e);
   printf("\n");
} 

Additional query words: 6.00 6.00a 6.00ax 7.00 8.00 8.00c 1.00 1.50

Keywords : kbCodeGen
Version : winnt:
Platform : winnt
Issue type :


Last Reviewed: February 2, 2000
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.