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.nl
gary@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.com
david@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