]> rtime.felk.cvut.cz Git - ulut.git/blobdiff - ulut/ul_utdefs.h
Do not use standard defined __alignof__ for structure filed alignment determination.
[ulut.git] / ulut / ul_utdefs.h
index adee9bda5443d5eece4e343946949b42a61a14fb..c49630b9a6094b8f8343f2786fd633c13ee50173 100644 (file)
@@ -66,6 +66,24 @@ extern "C" {
 #endif /*__GNUC__*/
 #endif /*UL_CONTAINEROF*/
 
+#ifndef UL_ALIGNOF_FIELD
+#define        UL_ALIGNOF_FIELD(_type) UL_OFFSETOF(struct {char _fld0; _type _fld1;}, _fld1)
+#endif /*UL_ALIGNOF*/
+
+#ifndef UL_ALIGNOF_TYPE
+#ifdef  __GNUC__
+/* The compiler provided alignment for performance can differ from ABI struct one */
+#define        UL_ALIGNOF_TYPE(_type) __alignof__(_type)
+#else /*__GNUC__*/
+#define UL_ALIGNOF_TYPE UL_ALIGNOF_FIELD
+#endif /*__GNUC__*/
+#endif /*UL_ALIGNOF*/
+
+#ifndef UL_ALIGNOF
+#define        UL_ALIGNOF UL_ALIGNOF_FIELD
+#endif /*UL_ALIGNOF*/
+
+
 #ifndef UL_NOPSTATEMENT
 #define UL_NOPSTATEMENT do { } while(0)
 #endif
@@ -150,26 +168,36 @@ extern "C" {
 #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() \
+  ) \
+)
+#define UL_CAST_UNQX_NULL_ALLOWED(ref_asterisks, new_type, expr) ( \
+  __builtin_choose_expr(!__builtin_types_compatible_p(void *, typeof(expr)), \
+    UL_CAST_UNQX(ref_asterisks, new_type, expr), \
+    expr \
   ) \
-  (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)
@@ -180,6 +208,14 @@ extern "C" {
 #define UL_CAST_UNQ3(new_type, expr) \
   UL_CAST_UNQX(**, new_type, expr)
 
+#ifndef UL_CAST_UNQX_NULL_ALLOWED
+#define UL_CAST_UNQX_NULL_ALLOWED(ref_asterisks, new_type, expr) \
+  UL_CAST_UNQX(ref_asterisks, new_type, expr)
+#endif /*UL_CAST_UNQX_NULL_ALLOWED*/
+
+#define UL_CAST_UNQ1_NULL_ALLOWED(new_type, expr) \
+  UL_CAST_UNQX_NULL_ALLOWED(*, new_type, expr)
+
 #ifdef __cplusplus
 } /* extern "C"*/
 #endif