bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question about portability guidelines


From: Ben Pfaff
Subject: Re: Question about portability guidelines
Date: Wed, 4 Jan 2017 09:28:11 -0800
User-agent: Mutt/1.5.23 (2014-03-12)

On Tue, Jan 03, 2017 at 04:33:24PM -0800, Paul Eggert wrote:
> (An aside: It's typically safer in C to assign to a typed temporary than
> to cast to the type, as casts are too powerful. This is orthogonal to
> the long-vs-ptrdiff_t issue.)

Yes.

Sometimes, to make casts safer, I declare macros to help out, like
CONST_CAST below.

For safer "casting" to intmax_t, I guess that one could just write a
function:

intmax_t to_intmax(intmax_t x) { return x; }

/* 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.

   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))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]