This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/43755] New: Bit shifting by a 8 byte variable isn't the same as bit shifting by an 8 or a 4 byte constant on 64bit platform.
- From: "mail dot alexhaase at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 15 Apr 2010 03:15:52 -0000
- Subject: [Bug c/43755] New: Bit shifting by a 8 byte variable isn't the same as bit shifting by an 8 or a 4 byte constant on 64bit platform.
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
I found four constant unsigned long (64bit) values which do not agree with bit
shifting ~0 by an unsigned long variable holding the value 32 (demo attached):
1) shifting ~0 by 32
2) shifting ~0 by (unsigned long)32
3) shifting ~((unsigned long)0) by (unsigned long) 32
4) shifting ~((unsigned long)0) by 32
One and two are the same(0), and three and four are the
same(18446744069414584320). However, letting unsigned long a=32 and mask=~0<<a
results in mask being unsigned long ~0 (18446744073709551615).
It seems to me at compile time gcc is computing the values 1-4 and storing
them(3 and 4 are the values I'd have expected from ~0<<a). However the run time
value doesn't make any sense at all to me, as if gcc is mixing 32bit and 64bit
register use.
I got around the bug in my production code by casting 0 to unsigned long.
However, the other value just doesn't make sense with casting I can dream up.
The demo computes values 1)-4) and then continuously evaluates mask=~0<<a until
mask agrees with any of 1)-4).
test.i:
# 1 "./test.c"
# 1 "/home/alex/malloc/avmalloc/bug//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "./test.c"
int main(void) {
unsigned long mask;
unsigned long lower_set_bit=32;
unsigned long a;
unsigned long b;
unsigned long c;
unsigned long d;
a= ~0 <<(unsigned long)32;
b= ~((unsigned long)0) << (unsigned long) 32;
c= ~0 << 32;
d= ~((unsigned long)0) <<32;
do {
mask=(~(0) << lower_set_bit);
} while(mask!=a && mask!=b && mask!=c && mask!=d);
return 0;
--
Summary: Bit shifting by a 8 byte variable isn't the same as bit
shifting by an 8 or a 4 byte constant on 64bit
platform.
Product: gcc
Version: 4.4.1
Status: UNCONFIRMED
Severity: minor
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: mail dot alexhaase at gmail dot com
GCC build triplet: x86_64-linux-gnu
GCC host triplet: x86_64-linux-gnu
GCC target triplet: x86_64-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43755