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


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.tar.gz
Description: GNU Zip compressed data

Reply via email to