X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fcast%2Fcast.h;h=cd384c4636d8e5a51fa2ba55f97ff162b5dff84a;hp=2fa96445b338f6b6b341b3f2aad122963e91054e;hb=be24e496578d7c03bc2fd6239887266e82c8d6da;hpb=3f4e83d8ac847d6bf0c20e88cdbca535e842a97b diff --git a/ccan/cast/cast.h b/ccan/cast/cast.h index 2fa96445..cd384c46 100644 --- a/ccan/cast/cast.h +++ b/ccan/cast/cast.h @@ -1,6 +1,8 @@ +/* Licensed under LGPLv2.1+ - see LICENSE file for details */ #ifndef CCAN_CAST_H #define CCAN_CAST_H #include "config.h" +#include #include /** @@ -13,8 +15,8 @@ * only differs in signed/unsigned, not in type or const-ness. */ #define cast_signed(type, expr) \ - ((type)(expr) \ - + BUILD_ASSERT_OR_ZERO(cast_sign_compatible(type, (expr)))) + (0 ? BUILD_ASSERT_OR_ZERO(cast_sign_compatible(type, (expr))) : \ + (type)(expr)) /** * cast_const - remove a const qualifier from a pointer. @@ -24,6 +26,10 @@ * This ensures that you are only removing the const qualifier from an * expression. The expression must otherwise match @type. * + * We cast via intptr_t to suppress gcc's -Wcast-qual (which SAMBA + * uses), and via the ? : so Sun CC doesn't complain about the result + * not being constant. + * * If @type is a pointer to a pointer, you must use cast_const2 (etc). * * Example: @@ -32,14 +38,14 @@ * { * size_t i; * for (i = 0; i < strlen(haystack); i++) - * if (memcmp("needle", haystack+i, strlen("needle")) == 0) - * return cast_const(char *, haystack+i); + * if (memcmp("needle", haystack+i, strlen("needle")) == 0) + * return cast_const(char *, haystack+i); * return NULL; * } */ -#define cast_const(type, expr) \ - ((type)(expr) \ - + BUILD_ASSERT_OR_ZERO(cast_const_compat1((expr), type))) +#define cast_const(type, expr) \ + (0 ? BUILD_ASSERT_OR_ZERO(cast_const_compat1((expr), type)) : \ + (type)(intptr_t)(expr)) /** * cast_const2 - remove a const qualifier from a pointer to a pointer. @@ -49,9 +55,9 @@ * This ensures that you are only removing the const qualifier from an * expression. The expression must otherwise match @type. */ -#define cast_const2(type, expr) \ - ((type)(expr) \ - + BUILD_ASSERT_OR_ZERO(cast_const_compat2((expr), type))) +#define cast_const2(type, expr) \ + (0 ? BUILD_ASSERT_OR_ZERO(cast_const_compat2((expr), type)) : \ + (type)(intptr_t)(expr)) /** * cast_const3 - remove a const from a pointer to a pointer to a pointer.. @@ -61,9 +67,9 @@ * This ensures that you are only removing the const qualifier from an * expression. The expression must otherwise match @type. */ -#define cast_const3(type, expr) \ - ((type)(expr) \ - + BUILD_ASSERT_OR_ZERO(cast_const_compat3((expr), type))) +#define cast_const3(type, expr) \ + (0 ? BUILD_ASSERT_OR_ZERO(cast_const_compat3((expr), type)) : \ + (type)(intptr_t)(expr)) /** @@ -104,11 +110,11 @@ ) #define cast_const_strip1(expr) \ - __typeof__(*(struct { int z; __typeof__(expr) x; }){0}.x) + __typeof__(*(union { int z; __typeof__(expr) x; }){0}.x) #define cast_const_strip2(expr) \ - __typeof__(**(struct { int z; __typeof__(expr) x; }){0}.x) + __typeof__(**(union { int z; __typeof__(expr) x; }){0}.x) #define cast_const_strip3(expr) \ - __typeof__(***(struct { int z; __typeof__(expr) x; }){0}.x) + __typeof__(***(union { int z; __typeof__(expr) x; }){0}.x) #define cast_const_compat1(expr, type) \ __builtin_types_compatible_p(cast_const_strip1(expr), \ cast_const_strip1(type)) @@ -121,11 +127,8 @@ #else #define cast_sign_compatible(type, expr) \ (sizeof(*(type)0) == 1 && sizeof(*(expr)) == 1) -#define cast_const_compat1(expr, type) \ - (sizeof(*(expr)) == sizeof(*(type)0)) -#define cast_const_compat2(expr, type) \ - (sizeof(**(expr)) == sizeof(**(type)0)) -#define cast_const_compat3(expr, type) \ - (sizeof(***(expr)) == sizeof(***(type)0)) +#define cast_const_compat1(expr, type) (1) +#define cast_const_compat2(expr, type) (1) +#define cast_const_compat3(expr, type) (1) #endif #endif /* CCAN_CAST_H */