bug-gnulib
[Top][All Lists]
Advanced

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

Re: alignof failure


From: Simon Josefsson
Subject: Re: alignof failure
Date: Fri, 29 May 2009 11:01:53 +0200
User-agent: Gnus/5.110011 (No Gnus v0.11) Emacs/23.0.94 (gnu/linux)

Simon Josefsson <address@hidden> writes:

> Bruno Haible <address@hidden> writes:
>
>> Simon Josefsson wrote:
>>> The alignof module seems to have problems:
>>> 
>>> address@hidden:~/src/gnulib master$ gnulib-tool --test --with-tests alignof
>>> ...
>>> ../../gltests/test-alignof.c:41: error: negative width in bit-field 
>>> ‘verify_error_if_negative_size__’
>>
>> I reproduce with all versions of gcc since 3.1, on x86, when -malign-double
>> is not specified.
>>
>>   offsetof (struct { char slot1; double slot2; }, slot2)
>> is 4 by default, but 8 when -malign-double is specified.
>>
>> Whereas
>>   __alignof__ (double)
>> is always 8 on x86; this is even part of the GCC test suite [1].
>>
>> [2] says: "It turns out that the alignment of a type can differ from the
>>   alignment of a field of that type. In particular, on x86 alignof(double)
>>   is 8, but a double as a field has alignment 4."
>>
>> I'm not sure which one we should use in gnulib. Probably the "alignment of a
>> field of that type" semantics, because that's what we use alignof for?
>
> Yes.  I suggest adding a comment about this, or rename alignof to
> alignof_field to avoid confusion, and fix the self-test.  Maybe there
> could be an alignof_type macro too?

How about this patch?

The test-alignof self-test still fails, so I'd like to fix this
somehow.

/Simon

diff --git a/lib/alignof.h b/lib/alignof.h
index 3752ef3..15fa56b 100644
--- a/lib/alignof.h
+++ b/lib/alignof.h
@@ -27,7 +27,17 @@
   template <class type> struct alignof_helper { char __slot1; type __slot2; };
 # define alignof(type) offsetof (alignof_helper<type>, __slot2)
 #else
-# define alignof(type) offsetof (struct { char __slot1; type __slot2; }, 
__slot2)
+# define alignof(type) \
+  offsetof (struct { char __slot1; type __slot2; }, __slot2)
+#endif
+
+/* Determine the alignment of a type in a struct, at compile time.  */
+#if defined __cplusplus
+template <class type> struct alignof_helper { char __slot1; type __slot2; };
+# define alignof_field(type) offsetof (alignof_helper<type>, __slot2)
+#else
+# define alignof_field(type) \
+  offsetof (struct { char __slot1; type __slot2; }, __slot2)
 #endif
 
 #endif /* _ALIGNOF_H */
diff --git a/lib/sys_socket.in.h b/lib/sys_socket.in.h
index 4553f60..5f71f34 100644
--- a/lib/sys_socket.in.h
+++ b/lib/sys_socket.in.h
@@ -53,11 +53,11 @@ typedef unsigned short  sa_family_t;
    2009-05-08, licensed under LGPLv2.1+, plus portability fixes. */
 # define __ss_aligntype unsigned long int
 # define _SS_SIZE 256
-# define _SS_PADSIZE \
-    (_SS_SIZE - ((sizeof (sa_family_t) >= alignof (__ss_aligntype)     \
-                 ? sizeof (sa_family_t)                                \
-                 : alignof (__ss_aligntype))                           \
-                + sizeof (__ss_aligntype)))
+# define _SS_PADSIZE                                                   \
+  (_SS_SIZE - ((sizeof (sa_family_t) >= alignof_field (__ss_aligntype) \
+               ? sizeof (sa_family_t)                                  \
+               : alignof_field (__ss_aligntype))                       \
+              + sizeof (__ss_aligntype)))
 
 struct sockaddr_storage
 {
diff --git a/tests/test-alignof.c b/tests/test-alignof.c
index 851cbf0..789b9c1 100644
--- a/tests/test-alignof.c
+++ b/tests/test-alignof.c
@@ -38,12 +38,29 @@ CHECK (short)
 CHECK (int)
 CHECK (long)
 CHECK (float)
-CHECK (double)
+/* The alignment of double can be different from the alignment of double
+   in a struct, so we can't use this test.
+   CHECK (double) */
 CHECK (struct1)
 CHECK (struct2)
 CHECK (struct3)
 CHECK (struct4)
 
+#define CHECKFIELD(type)                                           \
+  typedef struct { char slot1; type slot2; } type##_helper2;           \
+  verify (alignof_field (type) == offsetof (type##_helper2, slot2));
+
+CHECKFIELD (char)
+CHECKFIELD (short)
+CHECKFIELD (int)
+CHECKFIELD (long)
+CHECKFIELD (float)
+CHECKFIELD (double)
+CHECKFIELD (struct1)
+CHECKFIELD (struct2)
+CHECKFIELD (struct3)
+CHECKFIELD (struct4)
+
 int
 main ()
 {




reply via email to

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