linden@fwi.uva.nl (Onno van der Linden) (02/21/90)
Was my brain working OK when I saw the program below,after compiling
with Microsoft C 5.1,produce "Yes" as its output??
main()
{
	int	i = 0;
	long	l = -1;
	if (l >= (i&1)) puts("Yes");
	else puts("No");
}
Onno van der Linden
linden@fwi.uva.nlgary@hpavla.AVO.HP.COM (Gary Jackoway) (02/21/90)
> / hpavla:comp.lang.c / linden@fwi.uva.nl (Onno van der Linden) / 12:27 pm Feb 20, 1990 / > Was my brain working OK when I saw the program below,after compiling > with Microsoft C 5.1,produce "Yes" as its output?? > > main() > { > int i = 0; > long l = -1; > > if (l >= (i&1)) puts("Yes"); > else puts("No"); > } > Onno van der Linden > linden@fwi.uva.nl ---------- I verified your result. Further, if you change the int to a short the same thing happens. And the result on UN*X is "No" (at least on HP-UX 7.0). I played around some more and replaced the "l" with "-1". Same thing. The problem seems to be that the binary & operator is returning an unsigned result, even though the manual says "the type of the result is the type of the operators after [the usual arithmetic] conversion". I also put a (short) in front of the "1" and again got "Yes". This appears to me to be a real bug. You can work around the problem by saying "(int)(i&1)" or "(long)(i&1)". Anything to re-sign the result after the "&". You need to do this, of course, only when you are mixing bit-wise operators with signed comparisons. Gary Jackoway
kdq@demott.COM (Kevin D. Quitt) (02/22/90)
    Your head was on right; I couldn't believe it either.  I suspected
then disproved: 1) -1 generated 0x0000FFFF instead of 0xFFFFFFFF, 2) an
unsigned comparison.
    The generated test code is completely bogus.  In fact, it is such a lose
that the optimiser COMPLETELY ELIMINATES THE TEST!
              Code generated with optimization disabled:
$SG106  DB      'yes',  00H
$SG108  DB      'no',  00H
;|***   int             i = 0;
        mov     WORD PTR [bp-2],0       ;i
;|***   long    l = -1;
        mov     WORD PTR [bp-6],-1      ;l
        mov     WORD PTR [bp-4],-1
;|***   if ( l  >=  (i & 1 ) )
        mov     al,BYTE PTR [bp-2]      ;i
        and     ax,1
        sub     dx,dx
        cmp     dx,WORD PTR [bp-4]
        jbe     $JCC37
        jmp     $I104
$JCC37:
        jae     $JCC42
        jmp     $L20001
$JCC42:
        cmp     ax,WORD PTR [bp-6]      ;l
        jbe     $JCC50
        jmp     $I104
$JCC50:
$L20001:
;|***           puts( "yes" );
        mov     ax,OFFSET DGROUP:$SG106
        push    ax
        call    _puts
        add     sp,2
;|***   else
        jmp     $I107
                                $I104:
;|***           puts( "no" );
        mov     ax,OFFSET DGROUP:$SG108
        push    ax
        call    _puts
        add     sp,2
$I107:
;|***    }
$EX101:
              Code generated from optimised compilation:
$SG143  DB      'yes',  00H
$SG145  DB      'no',  00H
;|***   int             i = 0;
        mov     WORD PTR [bp-2],0       ;i
;|***   long    l = -1;
        mov     WORD PTR [bp-6],-1      ;l
        mov     WORD PTR [bp-4],-1
 
;|***   if ( l  >=  (i & 1 ) )
;|***           puts( "yes" );
        mov     ax,OFFSET DGROUP:$SG143
        push    ax
        call    _puts
;|***   else
;|***           puts( "no" );
;|***    }
    Amazing (shake of the head).
kdq
-- 
Kevin D. Quitt                          Manager, Software Development
DeMott Electronics Co.                  VOICE (818) 988-4975
14707 Keswick St.                       FAX   (818) 997-1190
Van Nuys, CA  91405-1266                MODEM (818) 997-4496 Telebit PEP last
34 12 N  118 27 W                       srhqla!demott!kdq   kdq@demott.comdavid@csource.oz.au (david nugent) (02/25/90)
In a message dated 22-Feb-90, Kevin D. Quitt writes: >Your head was on right; I couldn't believe it either. I suspected >then disproved: 1) -1 generated 0x0000FFFF instead of 0xFFFFFFFF, 2) an >unsigned comparison. > > >;|*** if ( l >= (i & 1 ) ) This is fairly typical behaviour. I've seen similar things on a number of compilers, though I can't find any reason why automatic type conversions should do this. 'l' is being resolved as an int prior the comparison. Try: if ( l >= (long) (i & 1) ) and you'll get something quite different. david -- UUCP: ...!munnari!csource!david <Fido/ACSNET Gate> Internet: david@csource.oz.au FidoNet: 3:632/348