FIX: Bitwise AND in a Conditional Expression Fails

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

The information in this article applies to:

  • The Microsoft C/C++ Compiler (CL.EXE) included with Microsoft Visual C++ 32-bit Edition, version 1.0

SYMPTOMS

Compiling code using the bitwise AND operator on signed integer literals in a conditional statement will produce incorrect results.

CAUSE

The problem is that the 16-bit test instruction used by the version 8.0 compiler toggles the sign-bit flag. This triggers the JLE (Jump Less than or Equal) to jump to the failure case when it should just fall thru to the passing case.

The version 9.0 compiler generates this correctly by using the 32-bit version of the test operator to evaluate the entire 32-bit register (EAX).

Assembly code generated using the version 8.0 compiler:

; 20   :     if ((tmp & 0x80) > 0)

  00157 0f be 45 f8     movsx   eax, BYTE PTR _tmp$[ebp]
  0015b a8 80           test    al, 128         ; 00000080H


Assembly code generated using the version 9.0 (x86) compiler:

; 20   :     if ((tmp & 0x80) > 0)

  00157 0f be 45 f8     movsx   eax, BYTE PTR _tmp$[ebp]
  0015b a9 80 00 00 00  test    eax, 128        ; 00000080H


RESOLUTION

Caste the integer literals to unsigned integers to force the correct results. For example, use:

   if ((tmp & 0x80U) > 0)

   -or-

   if ((tmp & (unsigned)0x80) > 0)

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This bug was corrected in Visual C++ version 2.0.

MORE INFORMATION

Sample Code to Reproduce Problem

/*
   Compile options needed: none
*/

#include <stdio.h>

void main()
{
   char tmp = 0x82;

   if ((tmp & 0x80) > 0)    // This should return true since the
      printf("True\n");     // result of the bitwise AND operation is
   else                     // an integer 0x00000080 and is definitely
      printf("False\n");    // greater than zero (0).
}


Additional reference words: 1.00 8.00 buglist1.00 fixlist2.00
KBCategory: kbtool kbfixlist kbbuglist
KBSubcategory: CodeGen
Keywords : CodeGen kbbuglist kbfixlist kbtool
Version : 1.00
Platform : NT 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.