FIX: Bitwise AND in a Conditional Expression Fails

ID: Q123494

1.00 WINDOWS NT kbtool kbfixlist kbbuglist

The information in this article applies to:

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          : kbCodeGen kbbuglist kbfixlist
Version           : 1.00
Platform          : NT WINDOWS
Solution Type     : kbfix

Last Reviewed: September 21, 1997