X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fcast.h;h=1e33857c1e3afa0a879512378df55694ca3900bc;hb=b3b8cd820da3100f7ad474a5ab88e2737da18d1b;hp=f74442c2cea7cb4f99c85d2a6fb3d1e026505f68;hpb=12895f38b01137ae0b14f07d26e6f0928b735bdf;p=pspp diff --git a/src/libpspp/cast.h b/src/libpspp/cast.h index f74442c2ce..1e33857c1e 100644 --- a/src/libpspp/cast.h +++ b/src/libpspp/cast.h @@ -19,12 +19,70 @@ #include +/* Expands to a void expression that checks that POINTER is an + expression whose type is a qualified or unqualified version of + a type compatible with TYPE (a pointer type) and, if not, + causes a compiler warning to be issued (on typical compilers). + + Examples: + + int *ip; + const int *cip; + const int **cipp; + int ***ippp; + double *dp; + + // None of these causes a warning: + CHECK_POINTER_HAS_TYPE (ip, int *); + CHECK_POINTER_HAS_TYPE (ip, const int *); + CHECK_POINTER_HAS_TYPE (cip, int *); + CHECK_POINTER_HAS_TYPE (cip, const int *); + CHECK_POINTER_HAS_TYPE (dp, double *); + CHECK_POINTER_HAS_TYPE (dp, const double *); + CHECK_POINTER_HAS_TYPE (cipp, const int **); + CHECK_POINTER_HAS_TYPE (cipp, const int *const *); + CHECK_POINTER_HAS_TYPE (ippp, int ***); + CHECK_POINTER_HAS_TYPE (ippp, int **const *); + + // None of these causes a warning either, although it is unusual to + // const-qualify a pointer like this (it's like declaring a "const int", + // for example). + CHECK_POINTER_HAS_TYPE (ip, int *const); + CHECK_POINTER_HAS_TYPE (ip, const int *const); + CHECK_POINTER_HAS_TYPE (cip, int *const); + CHECK_POINTER_HAS_TYPE (cip, const int *const); + CHECK_POINTER_HAS_TYPE (cipp, const int **const); + CHECK_POINTER_HAS_TYPE (cipp, const int *const *const); + CHECK_POINTER_HAS_TYPE (ippp, int ***const); + CHECK_POINTER_HAS_TYPE (ippp, int **const *const); + + // Provokes a warning because "int" is not compatible with "double": + CHECK_POINTER_HAS_TYPE (dp, int *); + + // Provoke warnings because C's type compatibility rules only allow + // adding a "const" qualifier to the outermost pointer: + CHECK_POINTER_HAS_TYPE (ippp, const int ***); + CHECK_POINTER_HAS_TYPE (ippp, int *const**); +*/ +#define CHECK_POINTER_HAS_TYPE(POINTER, TYPE) \ + ((void) sizeof ((TYPE) (POINTER) == (POINTER))) + /* Given expressions A and B, both of which have pointer type, expands to a void expression that causes a compiler warning if A and B are not pointers to qualified or unqualified versions - of compatible types. */ + of compatible types. + + Examples similar to those given for CHECK_POINTER_HAS_TYPE, + 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)) + /* Given POINTER, a pointer to the given MEMBER within structure STRUCT, returns the address of the STRUCT. */ #define UP_CAST(POINTER, STRUCT, MEMBER) \