X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fcast.h;h=5c64fac864a8e1eb78588dcc7558177d759ce0e1;hb=d775f576e4ffc0973c5f183b57b2baa089f555dc;hp=30927899c8bfb81dee56d509d16d7a5a3a72f52e;hpb=0b0a278699196c25f4cf0f690e21c5aea2ccabfb;p=pspp diff --git a/src/libpspp/cast.h b/src/libpspp/cast.h index 30927899c8..5c64fac864 100644 --- a/src/libpspp/cast.h +++ b/src/libpspp/cast.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #define LIBPSPP_CAST_H 1 #include +#include "gl/verify.h" /* Expands to a void expression that checks that POINTER is an expression whose type is a qualified or unqualified version of @@ -76,6 +77,35 @@ above, can easily be devised. */ #define CHECK_POINTER_COMPATIBILITY(A, B) ((void) sizeof ((A) == (B))) +/* Equivalent to casting POINTER to TYPE, but also issues a + warning if the cast changes anything other than an outermost + "const" or "volatile" qualifier. */ +#define CONST_CAST(TYPE, POINTER) \ + (CHECK_POINTER_HAS_TYPE (POINTER, TYPE), \ + (TYPE) (POINTER)) + +/* Casts POINTER to TYPE. Yields a compiler diagnostic if either TYPE or + POINTER is not a pointer to character type. + + PSPP uses "unsigned char" (actually uint8_t) in "union value" and "char" + elsewhere to emphasize that data in union value usually requires reencoding + when transferred to and from other string types. These macros suppress the + warning when implicitly converting between pointers to different character + types, so their use normally marks a bug that should eventually be fixed. + However, until these bugs are fixed, suppressing the warnings is much less + annoying. + + Use CHAR_CAST_BUG if you think there is a bug to be fixed, or if you have + not yet carefully examined the situation, or if you are not sure. + Use CHAR_CAST if you are convinced that this is actually a correct cast. */ +#define CHAR_CAST(TYPE, POINTER) \ + ((void) verify_true (sizeof (*(POINTER)) == 1), \ + (void) (sizeof (*(POINTER) + 1)), \ + (void) verify_true (sizeof (*(TYPE) NULL) == 1), \ + (void) (sizeof (*(TYPE) NULL + 1)), \ + (TYPE) (POINTER)) +#define CHAR_CAST_BUG(TYPE, POINTER) CHAR_CAST(TYPE, POINTER) + /* Given POINTER, a pointer to the given MEMBER within structure STRUCT, returns the address of the STRUCT. */ #define UP_CAST(POINTER, STRUCT, MEMBER) \