BUG: Bad Code for Comparison of long When Compiling for 80386

Last reviewed: July 22, 1997
Article ID: Q112564
1.00 1.50 WINDOWS kbtool 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 and 1.5

SYMPTOMS

The compiler generates incorrect code for a comparison involving a variable of type long. The generated code may crash or behave unpredictably if the code is compiled with /G3, to target the 80386 processor.

CAUSE

In comparisons involving more than one long variable, the compiler may generate incorrect code when the /G3 option is used.

RESOLUTION

To avoid the problem, one option is to use the /G2 compiler switch instead of the /G3 compiler switch. Another option is to break up the boolean expression that involves more than one long variable comparison, as demonstrated in the sample below.

STATUS

Microsoft has confirmed this to be a problem in C/C++ for MS-DOS versions 8.0 and 8.0c. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

This is not a problem in the 32-bit compiler.

MORE INFORMATION

Sample Code

/* Compile options needed: /f- /G3
*/

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

struct test {
    long field1;
    long field2;
};

void main ()
{
    int bTest;
    struct test * pTest;

    pTest= (struct test *) malloc (sizeof (struct test));


    pTest->field1= -8L;
    if ((0 > pTest->field1) && (pTest->field1 != -8L))
    {
        printf ("Error - small negative - this should not execute\n");
    }
    // Work around for this test starts here!
    bTest= (0 > pTest->field1);
    bTest= (bTest && (pTest->field1 != -8L));
    if (bTest)
        printf ("The work around failed\n");
    else
        printf ("This is the work around\n");


    pTest->field1= -65544L;
    if ((0 > pTest->field1) && (pTest->field1 != -65544L))
    {
        printf ("Error - large negative - this should not execute\n");
    }
    // Work around for this test starts here!
    bTest= (0 > pTest->field1);
    bTest= (bTest && (pTest->field1 != -65544L));
    if (bTest)
        printf ("The work around failed\n");
    else
        printf ("This is the work around\n");


    pTest->field1= 8L;
    if ((0 < pTest->field1) && (pTest->field1 != 8L))
    {
        printf ("Error - small positive - this will not execute\n");
    }

    pTest->field1= 65544L;
    if ((0 < pTest->field1) && (pTest->field1 != 65544L))
    {
        printf ("Error - large positive - this will not execute\n");
    }
}


Additional reference words: 8.00 8.00c 1.00 1.50
KBCategory: kbtool kbbuglist
KBSubcategory: CodeGen
Keywords : kb16bitonly


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: July 22, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.