Hi, gcc 4.1 changed the typeof behaviour and now includes the type const qualifier, which unfortunately breaks existing code. The example below is simplified example from the Linux kernel (i386 was "fixed", but that's not the only arch).
The first get_user() produces nice code with 4.0 and earlier, but it breaks with 4.1 and so far I have not been able to produce an equivalent version. It either produces warnings and/or it produces worse code or it is less flexible (the second get_user() is one example). How can I get this working? How can get rid of the const qualifier? In other examples (like max()), it's possible to work around it by including the initialization with the definition, but if the variable is initialized via an asm() this isn't possible. bye, Roman #if 1 #define get_user(p) ({ \ typeof (*(p)) _v; \ \ switch (sizeof(*(p))) { \ case 1: \ asm volatile ("#1: %0 = %1" : "=r" (_v) : "m" (*p)); \ break; \ case 2: \ asm volatile ("#2: %0 = %1" : "=r" (_v) : "m" (*p)); \ break; \ case 4: \ asm volatile ("#4: %0 = %1" : "=r" (_v) : "m" (*p)); \ break; \ case 8: \ asm volatile ("#8: %0 = (%1)" : "=r" (_v) : "a" (p)); \ break; \ } \ _v; \ }) #else #define get_user(p) ({ \ long long _v; \ \ switch (sizeof(*(p))) { \ case 1: { \ char __v; \ asm volatile ("#1: %0 = %1" : "=r" (__v) : "m" (*p)); \ _v == __v; \ break; } \ case 2: { \ short __v; \ asm volatile ("#2: %0 = %1" : "=r" (__v) : "m" (*p)); \ _v == __v; \ break; } \ case 4: { \ int __v; \ asm volatile ("#4: %0 = %1" : "=r" (__v) : "m" (*p)); \ _v == __v; \ break; } \ case 8: { \ long long __v; \ asm volatile ("#8: %0 = (%1)" : "=r" (__v) : "a" (p)); \ _v == __v; \ break; } \ } \ (typeof (*(p)))_v; \ }) #endif typedef void *void_ptr; char test1(char *p) { return get_user(p); } short test2(short *p) { return get_user(p); } int test3(int *p) { return get_user(p); } long long test4(long long *p) { return get_user(p); } void_ptr test5(void_ptr *p) { return get_user(p); } int test6(short *p) { return get_user(p); } char test7(short *p) { return get_user(p); } char test8(const char *p) { return get_user(p); } short test9(const short *p) { return get_user(p); } int test10(const int *p) { return get_user(p); } long long test11(const long long *p) { return get_user(p); } void_ptr test12(const void_ptr *p) { return get_user(p); } int test13(const short *p) { return get_user(p); } char test14(const short *p) { return get_user(p); }