Q115704: FIX: Loop Optimization Causes Infinite Do-While Loop

Article: Q115704
Product(s): Microsoft C Compiler
Version(s): winnt:
Operating System(s): 
Keyword(s): kbCodeGen kbfixkbbuglist kbfixlist
Last Modified: 26-JUL-2001

-------------------------------------------------------------------------------
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++, versions 1.0, 1.5 
   - *EDITOR Please do not choose this product*Microsoft Visual C++ 32-bit Edition* use 241, 265, 225, 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 query words: 6.00 6.00a 6.00ax 7.00 8.00 8.00c 1.00 1.50

======================================================================
Keywords          : kbCodeGen kbfix kbbuglist kbfixlist
Technology        : kbVCsearch kbAudDeveloper kbCVCComp
Version           : winnt:
Issue type        : kbbug
Solution Type     : kbfix

=============================================================================