FIX: Loop Optimization Causes Infinite Do-While Loop

Last reviewed: September 18, 1997
Article ID: Q115704
6.00 6.00a 6.00ax 7.00 | 1.00 1.50 | 1.00
MS-DOS                 | WINDOWS   | WINDOWS NT
kbtool kbfixlist kbbuglist

The information in this article applies to:

  • The Microsoft C/C++ Compiler (CL.EXE), included with:

        - Microsoft C for MS-DOS, versions 6.0, 6.0a, and 6.0ax
        - Microsoft C for OS/2, versions 6.0 and 6.0a
        - Microsoft C/C++ for MS-DOS, version 7.0
        - Microsoft Visual C++ for Windows, versions 1.0 and 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.

    -or-

  2. 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 reference words: 6.00 6.00a 6.00ax 7.00 8.00 8.00c 1.00 1.50
KBCategory: kbtool kbfixlist kbbuglist
KBSubcategory: CodeGen
Keywords : CodeGen kbbuglist kbfixlist kbtool
Version : 6.00 6.00a 6.00ax 7.00 | 1.00 1.
Platform : MS-DOS NT WINDOWS
Solution Type : kbfix


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.