Pavel Pisa ppisa4lists at pikron.com
Sun Sep 7 20:34:42 UTC 2014

Hello Sebastian and Joel,

On Friday 05 of September 2014 16:04:40 Sebastian Huber wrote:
> On 05/09/14 15:53, Joel Sherrill wrote:
> > Why add these?
> To be independent of Newlib.  We can also use the one in Newlib
> <sys/cdefs.h>, but we should use a common macro for this stuff, since this
> documents the intention and you can grep for it.

If there are not some other variants/tricks for these macros
which would be used for GCC/featured compilers, I do not feel
good about them.

They suppress relatively harmless warning which can be filterred
out by GCC options or pragmas for price of hiding serious problems
when pointer to incorrect type is used.

I fought with these in my projects some years ago and I have
been motivated by actual need of RTEMS to look at my solution again
and I think that I have found solution which should help to catch
most of mistakes and suppress warning about intentional qualifiers
removal. If the solution is not too obscure for your taste, I suggest
to adapt it for RTEMS. My latest changes allow to use qualifiers
removal macro even for global variables initializers even that
there is not produced nice diagnostic message "UL_CAST_UNQX types
differ not only by volatile and const" but "critic initializer is
not constant". Each of macros, UL_CAST_UNQ1, UL_CAST_UNQ2,
or UL_CAST_UNQ3 expects pointer of reference level 1/2/3
and removes const/volatile to given depth. I have been
inspired during my attempts by libHX from Jan Engelhardt
but my solution works even for global initializers
and I think that it is even simpler in the end.

Best wishes,



/* The cast idea based on libHX by Jan Engelhardt */
#define UL_TYPEOF_REFX(ref_asterisks, ptr_type) \
  typeof(ref_asterisks(union { int z; typeof(ptr_type) x; }){0}.x)

/* Const and volatile qualifiers removal cast */
#ifdef __cplusplus
#define UL_CAST_UNQX(ref_asterisks, new_type, expr) \
#else /* Standard C code */
#ifdef __GNUC__
#if  ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
extern void* UL_CAST_UNQX_types_not_compatible(void)
  __attribute__((error ("UL_CAST_UNQX types differ not only by volatile and const")));
extern void UL_CAST_UNQX_types_not_compatible(void);
#define UL_CAST_UNQX(ref_asterisks, new_type, expr) ( \
  __builtin_choose_expr(__builtin_types_compatible_p \
    (UL_TYPEOF_REFX(ref_asterisks, expr), \
     UL_TYPEOF_REFX(ref_asterisks, new_type)), \
    (new_type)(expr), \
    UL_CAST_UNQX_types_not_compatible() \
  ) \
#else /*__GNUC__*/
#define UL_CAST_UNQX(ref_asterisks, new_type, expr) ((new_type)(expr))
#endif /*__GNUC__*/
#endif /*__cplusplus*/

#define UL_CAST_UNQ1(new_type, expr) \
  UL_CAST_UNQX(*, new_type, expr)

#define UL_CAST_UNQ2(new_type, expr) \
  UL_CAST_UNQX(**, new_type, expr)

#define UL_CAST_UNQ3(new_type, expr) \
  UL_CAST_UNQX(**, new_type, expr)

More information about the devel mailing list