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