FIX: Code Movement with Huge Pointer Expression in Loop

Last reviewed: September 18, 1997
Article ID: Q114077
1.00 WINDOWS kbtool kbfixlist kbbuglist

The information in this article applies to:

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

        - Microsoft Visual C++ for Windows, versions 1.0
    

SYMPTOMS

In certain cases when the C/C++ compiler reorganizes code for efficiency after code generation, it will do it incorrectly. The generated code will not run as expected because of this. A specific example of this problem can be reproduced by building and running the sample code below.

RESOLUTION

To work around the problem illustrated by the sample code, do one of the following:

  • Disable post-code-generation optimizations for the module containing the function by compiling with the /Oo- option. This will prevent the compiler from rearranging the code that causes the problem.
  • Do not use the /Oe and /Ol options together when compiling the module containing the function.
  • Use the #pragma optimize() directive to disable the /Oe or /Ol options for the function. This is indicated in the sample code below.

STATUS

Microsoft has confirmed this to be a problem in the Microsoft products listed above. This problem was corrected in Visual C++ version 1.5.

MORE INFORMATION

The specific problem in the sample code below is that the code generated to test that n = 1 is rearranged. This causes the test to fail when it should not, so that the while loop is exited without looping.

Sample Code

/* Compile options needed: /Oel (or /O2, or /Ox; both include /Oel)
*/

#include <malloc.h>
#include <stdio.h>

#define COUNT 5

int dummy_fcn()
{
    static int accum;

    accum++;
    if ( accum <= COUNT )
        return 1;
    else
        return 0;
}

/*    uncomment #pragmas to correct problem
#pragma( "l", off )
*/

void main()
{
    int __huge *hptr;
    int n = 1;

    hptr = _fmalloc( sizeof( int ) );
    if ( hptr == NULL )
    {
        printf( "Test failed!\n" );
        exit( 1 );
    }
    *hptr = 0;

    while ( n == 1 )
    {
        /*
           dummy_fcn() will return 1, COUNT times.
           The reason this is done is to force the
           while loop to be executed a certain number
           of times, by keeping n = 1.
        */
        n = dummy_fcn();

        /*
           If the correct code is generated, the
           value pointed to by hptr should be
           incremented COUNT+1 times. Since it is
           initialized to 0 before the loop, its
           value after the loop should be COUNT+1.
        */
        *hptr = *hptr + 1;
    }

    if ( *hptr == COUNT+1 )
        printf( "Test succeeded!\n" );
    else
        printf( "Test failed!\n" );
}

/*
#pragma optimize( "l", on )
*/


Additional reference words: 8.00 1.00
KBCategory: kbtool kbfixlist kbbuglist
KBSubcategory: CLIss
Keywords : CLIss kb16bitonly kbbuglist kbfixlist kbtool
Version : 1.00
Platform : 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.