diff src/lisp.h @ 456:e7ef97881643 r21-2-43

Import from CVS: tag r21-2-43
author cvs
date Mon, 13 Aug 2007 11:41:24 +0200
parents d7a9135ec789
children c33ae14dd6d0
line wrap: on
line diff
--- a/src/lisp.h	Mon Aug 13 11:40:56 2007 +0200
+++ b/src/lisp.h	Mon Aug 13 11:41:24 2007 +0200
@@ -216,13 +216,10 @@
      "Types must be declared in declarations, not in expressions." */
 #  define ALIGNOF(type) offsetof (struct { char c; type member; }, member)
 # else
-/* The following should be completely portable, but might give values
-   that are larger than necessary.  But never larger than the maximum
-   possible alignment. */
-#  define ALIGNOF(type)				\
-((sizeof (type) % sizeof (max_align_t)) == 0 ?	\
- sizeof (max_align_t) :				\
- (sizeof (type) % sizeof (max_align_t)))
+/* C++ is annoying, but it has a big bag of tricks.
+   The following doesn't have the "inside out" declaration bug C does. */
+template<class T> struct alignment_trick { char c; T member; };
+#  define ALIGNOF(type) offsetof (alignment_trick<type>, member)
 # endif
 #endif /* ALIGNOF */
 
@@ -1203,14 +1200,28 @@
 
 #endif /* not MULE */
 
-/* Return the true size of a struct with a variable-length array field.  */
-#define FLEXIBLE_ARRAY_STRUCT_SIZEOF(flexible_array_structtype,		\
-				     flexible_array_field,		\
-				     flexible_array_length)		\
-  (offsetof (flexible_array_structtype, flexible_array_field) +		\
-   (offsetof (flexible_array_structtype, flexible_array_field[1]) -	\
-    offsetof (flexible_array_structtype, flexible_array_field[0])) *	\
-   (flexible_array_length))
+/* Return the true aligned size of a struct whose last member is a
+   variable-length array field.  (this is known as the "struct hack") */
+/* Implementation: in practice, structtype and fieldtype usually have
+   the same alignment, but we can't be sure.  We need to use
+   ALIGN_SIZE to be absolutely sure of getting the correct alignment.
+   To help the compiler's optimizer, we use a ternary expression that
+   only a very stupid compiler would fail to correctly simplify. */
+#define FLEXIBLE_ARRAY_STRUCT_SIZEOF(structtype,	\
+				     fieldtype,		\
+				     fieldname,		\
+				     array_length)	\
+(ALIGNOF (structtype) == ALIGNOF (fieldtype)		\
+ ? (offsetof (structtype, fieldname) +			\
+    (offsetof (structtype, fieldname[1]) -		\
+     offsetof (structtype, fieldname[0])) *		\
+    (array_length))					\
+ : (ALIGN_SIZE						\
+    ((offsetof (structtype, fieldname) +		\
+      (offsetof (structtype, fieldname[1]) -		\
+       offsetof (structtype, fieldname[0])) *		\
+      (array_length)),					\
+     ALIGNOF (structtype))))
 
 /*------------------------------ vector --------------------------------*/