From: Rusty Russell Date: Thu, 29 Mar 2012 04:28:33 +0000 (+1030) Subject: cast: make sure suncc sees a constant. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=74859ab18b10aaf990848e49d7789ff5c6cf96c6 cast: make sure suncc sees a constant. cast_const() et. al. are supposed to be a constant expression, so you can do things like: static char *p = cast_const(char *, (const char *)"hello"); Unfortunately, a cast to intptr_t and arithmetic makes suncc reject it as a constant expression. We need the cast, because (1) the expression could be a void *, so we can't just add to it, and (2) gcc complains with -Wcast-qual without it. So instead of adding BUILD_BUG_OR_ZERO, we use a ? :, which keeps everyone happy. --- diff --git a/ccan/cast/cast.h b/ccan/cast/cast.h index b108b0c8..1f3a7aac 100644 --- a/ccan/cast/cast.h +++ b/ccan/cast/cast.h @@ -15,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. @@ -26,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: @@ -40,8 +44,8 @@ * } */ #define cast_const(type, expr) \ - ((type)((intptr_t)(expr) \ - + BUILD_ASSERT_OR_ZERO(cast_const_compat1((expr), type)))) + (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. @@ -52,8 +56,8 @@ * expression. The expression must otherwise match @type. */ #define cast_const2(type, expr) \ - ((type)((intptr_t)(expr) \ - + BUILD_ASSERT_OR_ZERO(cast_const_compat2((expr), type)))) + (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.. @@ -64,8 +68,8 @@ * expression. The expression must otherwise match @type. */ #define cast_const3(type, expr) \ - ((type)((intptr_t)(expr) \ - + BUILD_ASSERT_OR_ZERO(cast_const_compat3((expr), type)))) + (0 ? BUILD_ASSERT_OR_ZERO(cast_const_compat3((expr), type)) : \ + (type)(intptr_t)(expr)) /** diff --git a/ccan/cast/test/compile_ok-static.c b/ccan/cast/test/compile_ok-static.c new file mode 100644 index 00000000..98b667e8 --- /dev/null +++ b/ccan/cast/test/compile_ok-static.c @@ -0,0 +1,10 @@ +/* OpenIndiana's CC (aka suncc) has issues with constants: make sure + * we are one! */ +#include + +static char *p = cast_const(char *, (const char *)"hello"); + +int main(int argc, char *argv[]) +{ + return p[0] == argv[0][0]; +}