Hi,
I'm not subscribed, so if you want to reach me directly you have to send an email directly to me; otherwise I'll pick up any answer via the web-archives.
I'm a little bit confused w.r.t. to signed/unsigned multiplication on x86_64:
Assume multiplying (signed <some integer type)-1 by (unsigned <same integer type)20 and cast that value to a larger integer. With gcc-3.4.3 (pretty sure head CVS is the same):
1. (signed long) = (signed int) = (signed short) = (signed char) x (unsigned char)
This yields proper (?) sign extension to every integer type. In hex notation:
a = -1 * 20, then a = 0xffff ffff ffff ffec
2. (signed long) = (signed int) = (signed short) x (unsigned short)
Dito.
a = -1 * 20, then a = 0xffff ffff ffff ffec
3. (signed long) = (signed int) x (unsigned int)
Surprisingly the sign is not promoted in this case:
a = -1 * 20, then a = 0x0000 0000 ffff ffec
IMHO, this is a bug. Below is a short test program which tries to execute the three scenarios.
Regards
Claus
############################ snip #################################### #include <stdio.h>
short char_mix(signed char sign, unsigned char val) { return sign * val; }
int short_mix(signed short sign, unsigned short val) { return sign * val; }
long int int_mix(int sign, unsigned int val) { return sign * val; }
int main(int argc, const char *argv[]) { short short_res; int int_res; long int long_int_res;
short_res = char_mix(-1, 20); int_res = short_mix(-1, 20); long_int_res = int_mix(-1, 20);
printf("Char : 0x%016lx | 0x%08x | 0x%04x\n", (unsigned long)short_res, (unsigned int)short_res, (unsigned short)short_res); printf("Short: 0x%016lx | 0x%08x\n", (unsigned long)int_res, (unsigned int)int_res); printf("Int : 0x%016lx\n", (unsigned long)long_int_res); } ############################ snap ####################################