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

Attachment: testing_long_GCC_march2007_2.tar.gz
Description: GNU Zip compressed data

Reply via email to