Hi people,
bug_mult_and_shift_long.c
-------------------------
#include <stdio.h> // it's for public domain by J.C. Pizarro, hahahahaha
int main() {
long long int a,b,c;
unsigned int hi_a,lo_a,hi_b,lo_b,hi_c,lo_c;
a = 10000000000L; // 10G
b = 100000000L; // 100M
c = a * b;
hi_a = (((unsigned long)a)>>32); // <- warning? why? (>>32)
hi_a = ((((unsigned long)a)>>31)>>1); // <- no warning! dirty workaround
lo_a = ((((unsigned long)(a<<32))>>31)>>1); // <- warning? why? (<<32)
lo_a = a; // <- no warning!
hi_b = ((((unsigned long)b)>>1)>>31);
lo_b = b & 0x00000000FFFFFFFFL;
hi_c = ((((unsigned long)c)>>16)>>16);
lo_c = c & 0x00000000FFFFFFFFL;
printf("a = %ld\n",a);
printf("b = %ld\n",b);
printf("c = a x b = %ld\n",c);
printf("high(a) = 0x%08X ; low(a) = 0x%08X\n",hi_a,lo_a);
printf("high(b) = 0x%08X ; low(b) = 0x%08X\n",hi_b,lo_b);
printf("high(c) = 0x%08X ; low(c) = 0x%08X\n",hi_c,lo_c);
printf("why this multiply?\n");
printf("It's a bug: long x long -> { 0, unsigned int } \
instead of long x long -> long\n");
return 0;
}
run.sh
------
#!/bin/sh
gcc bug_mult_and_shift_long.c
./a.out
rm -f a.out
run.log
-------
Reading specs from /usr/lib/gcc/i486-slackware-linux/3.4.6/specs
Configured with: ../gcc-3.4.6/configure --prefix=/usr --enable-shared
--enable-threads=posix --enable-__cxa_atexit --disable-checking
--with-gnu-ld --verbose --target=i486-slackware-linux
--host=i486-slackware-linux
Thread model: posix
gcc version 3.4.6
bug_mult_and_shift_long.c: In function `main':
bug_mult_and_shift_long.c:5: warning: integer constant is too large
for "long" type
bug_mult_and_shift_long.c:8: warning: right shift count >= width of type
a = 1410065408
b = 100000000
c = a x b = -1486618624
high(a) = 0x00000000 ; low(a) = 0x540BE400
high(b) = 0x00000000 ; low(b) = 0x05F5E100
high(c) = 0x00000000 ; low(c) = 0xA7640000
why this multiply?
It's a bug: long x long -> { 0, unsigned int } instead of long x long -> long
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ./configure --prefix=/opt/gcc413
Thread model: posix
gcc version 4.1.3 20070326 (prerelease)
bug_mult_and_shift_long.c: In function 'main':
bug_mult_and_shift_long.c:5: warning: integer constant is too large
for 'long' type
bug_mult_and_shift_long.c:8: warning: right shift count >= width of type
a = 1410065408
b = 100000000
c = a x b = -1486618624
high(a) = 0x00000000 ; low(a) = 0x540BE400
high(b) = 0x00000000 ; low(b) = 0x05F5E100
high(c) = 0x00000000 ; low(c) = 0xA7640000
why this multiply?
It's a bug: long x long -> { 0, unsigned int } instead of long x long -> long
Brief summary, there are 3 bugs:
1. Error and Warning in assignment of a long constant (with L letter)
(it's not true that a = 1410065408, high(a) = 0x00000000).
2. Warning in shifts << & >> of a long variable (i don't know if there
is an error).
3. Error in multiply of long variables. (it's not true that c = -1486618624).
Sincerely yours, J.C. Pizarro
testing_long_GCC_march2007_2.tar.gz
Description: GNU Zip compressed data
