DOCUMENT:Q115704 26-JUL-2001 [visualc] TITLE :FIX: Loop Optimization Causes Infinite Do-While Loop PRODUCT :Microsoft C Compiler PROD/VER:winnt: OPER/SYS: KEYWORDS:kbCodeGen kbfixkbbuglist kbfixlist ====================================================================== ------------------------------------------------------------------------------- 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 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 2001.