#define UL_TYPEOF_REFX(ref_asterisks, ptr_type) \
typeof(ref_asterisks(union { int z; typeof(ptr_type) x; }){0}.x)
-#ifdef __GNUC__
-/* Const and volatile qualifiers removal cast
- * The expression is cast by (typeof((typeof(new_type[1])){0}[0]))
- * which is equivalent to (new_type) cast for matching types.
- * This quite complicated method is used because both comma operator
- * and compound expressions are not allowed in global variables
- * initializers.
- */
+/* Const and volatile qualifiers removal cast */
+#ifdef __cplusplus
+#define UL_CAST_UNQX(ref_asterisks, new_type, expr) \
+ (const_cast<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")));
+#else
+extern void UL_CAST_UNQX_types_not_compatible(void);
+#endif
#define UL_CAST_UNQX(ref_asterisks, new_type, expr) ( \
- (typeof((typeof(new_type[1 - 2 * \
- !__builtin_types_compatible_p \
+ __builtin_choose_expr(__builtin_types_compatible_p \
(UL_TYPEOF_REFX(ref_asterisks, expr), \
- UL_TYPEOF_REFX(ref_asterisks, new_type)) \
- ])){0}[0]) \
+ UL_TYPEOF_REFX(ref_asterisks, new_type)), \
+ (new_type)(expr), \
+ UL_CAST_UNQX_types_not_compatible() \
) \
- (expr) \
)
#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)