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
=============================================================================
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.
Copyright Microsoft Corporation 1986-2002.