On Sun, Nov 07, 2010 at 03:37:36PM -0500, Hadriel Kaplan wrote:
>
> On Nov 7, 2010, at 12:33 PM, Jakub Zawadzki wrote:
> > Have you tried adding 'U' to your #define? i.e.
> >
> > instead of just:
> > #define VENDOR_FOO 0xdead
> >
> > do:
> > #define VENDOR_FOO 0xdeadU
> >
> > or even better:
> > #define VENDOR_FOO G_GUINT64_CONSTANT(0xdead) /* which should result in 0xdeadLLU */
>
> It won't help - if you force it to be bigger than an int,
I really don't want to force it bigger than int, I just want to make it unsigned.
cause:
(gdb) call /x (unsigned long long) (0xdead << 16)
$1 = 0xffffffffdead0000
(gdb) call /x (unsigned long long) (0xdeadU << 16)
$2 = 0xdead0000
and I'm afraid in your case (VENDOR_FOO << 16) is sign extended to uint64_t.
(btw. you can check it using disassembly)
> gcc errors that the switch's case statement is not an integer... and apparently ISO C agrees with it: switch/case is defined to use an int size
Well mine[1] version of C99 standard speaks only about *integer constants*, and unsigned long long constant is still integer one.
Can't find information about int size.
gcc-4.4.4 compiles & run attached test without problem (both on -m32 -m64)
Can you try it?
[1] http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
Regards.
#include <stdio.h>
#include <stdint.h>
#define VENDOR_FOO 0xdeadU
#define BIG64_VALUE 0xdeadbeafc0debeafLLU
void test(uint64_t pen_type) {
switch (pen_type) {
case BIG64_VALUE:
printf("BIG64_VALUE: %.16llx\n", pen_type);
break;
case (VENDOR_FOO << 16 | 3):
printf("VENDOR_FOO: %.16llx\n", pen_type);
break;
default:
printf("UNK: %.16llx\n", pen_type);
break;
}
}
int main() {
test((VENDOR_FOO << 16) | 3);
test(BIG64_VALUE);
test(-1);
}