bug-gnulib
[Top][All Lists]
Advanced

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

Re: stdalign: new module


From: Paul Eggert
Subject: Re: stdalign: new module
Date: Thu, 27 Oct 2011 13:16:06 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0) Gecko/20110927 Thunderbird/7.0

Thanks for all those comments.  I incorporated them and
pushed the stdalign code, with the following extra
patch, which I hope addresses all the comments.  I'm using
this in my test version of Emacs; see
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9772>.

One other thing: none of this stuff affects the existing
alignof module.  Perhaps the documentation for each should
refer to the other?  Maybe alignof should use stdalign?
(Obviously none of this is high priority.)


>From 610ca128a2e9199fcb4ae780dac2f7b34a65a4a6 Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
Date: Thu, 27 Oct 2011 12:43:51 -0700
Subject: [PATCH] Adjust to Bruno's comments.

---
 ChangeLog                       |    4 +++
 doc/posix-headers/stdalign.texi |    4 +-
 lib/stdalign.in.h               |   44 +++++++++++++++++++++++-------
 m4/stdalign.m4                  |   17 +-----------
 modules/stdalign                |    2 +-
 tests/test-stdalign.c           |   58 ++++++++++++++++++++++++++-------------
 6 files changed, 81 insertions(+), 48 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e862b7a..a776758 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2011-10-27  Paul Eggert  <address@hidden>
 
+       Add stdalign module and use it in other modules.
+       This is based on a previous proposal by Bruno Haible
+       <https://lists.gnu.org/archive/html/bug-gnulib/2011-07/msg00226.html>.
+
        stdalign: new module
        * doc/posix-headers/stdalign.texi, lib/stdalign.in.h, m4/stdalign.m4:
        * modules/stdalign: New files.
diff --git a/doc/posix-headers/stdalign.texi b/doc/posix-headers/stdalign.texi
index af37a38..32c582d 100644
--- a/doc/posix-headers/stdalign.texi
+++ b/doc/posix-headers/stdalign.texi
@@ -21,8 +21,8 @@ Portability problems not fixed by Gnulib:
 @code{_Alignas} and @code{alignas} are not always supported;
 on platforms lacking support, the
 macro @code{__alignas_is_defined} is not defined.
-Supported platforms includes GCC 2 and later, Sun C 5.11 and later,
-and MSVC 7.0 or later.
+Supported compilers include GCC, IBM C, Sun C 5.11 and later,
+and MSVC 7.0 and later.
 @item
 @code{<stdalign.h>} must be #included before @samp{_Alignas} and
 @samp{_Alignof} can be used.
diff --git a/lib/stdalign.in.h b/lib/stdalign.in.h
index 092dfed..8e64a2a 100644
--- a/lib/stdalign.in.h
+++ b/lib/stdalign.in.h
@@ -29,14 +29,18 @@
    C++0X <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf>
    section 18.10. */
 
-/* Return the alignment of a structure slot (field) of TYPE,
-   as an integer constant expression.  The result cannot be used as a
-   value for an 'enum' constant, if you want to be portable to HP-UX
-   10.20 cc and AIX 3.2.5 xlc.
-
-   This is not the same as GCC's __alignof__ operator; for example, on
-   x86 with GCC, _Alignof (long long) is typically 4 whereas
-   __alignof__ (long long) is 8.  */
+/* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment
+   requirement of a structure member (i.e., slot or field) that is of
+   type TYPE, as an integer constant expression.
+
+   This differs from GCC's __alignof__ operator, which can yield a
+   better-performing alignment for an object of that type.  For
+   example, on x86 with GCC, __alignof__ (double) and __alignof__
+   (long long) are 8, whereas alignof (double) and alignof (long long)
+   are 4 unless the option '-malign-double' is used.
+
+   The result cannot be used as a value for an 'enum' constant, if you
+   want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc.  */
 #include <stddef.h>
 #if defined __cplusplus
    template <class __t> struct __alignof_helper { char __a; __t __b; };
@@ -47,8 +51,28 @@
 #define alignof _Alignof
 #define __alignof_is_defined 1
 
-/* Align a type or variable to the alignment A.  */
-#if @HAVE_ATTRIBUTE_ALIGNED@ && !defined __cplusplus
+/* alignas (A), also known as _Alignas (A), aligns a variable or type
+   to the alignment A, where A is an integer constant expression.  For
+   example:
+
+      int alignas (8) foo;
+      struct s { int a; int alignas (8) bar; };
+
+   aligns the address of FOO and the offset of BAR to be multiples of 8.
+
+   A should be a power of two that is at least the type's alignment
+   and at most the implementation's alignment limit.  This limit is
+   2**28 on typical GNUish hosts, and 2**13 on MSVC.
+
+   The following draft C1X requirements are not supported here:
+
+     - If A is zero, alignas has no effect.
+     - alignas can be used multiple times; the strictest one wins.
+     - alignas (TYPE) is equivalent to alignas (alignof (TYPE)).
+
+   */
+
+#if __GNUC__ || __IBMC__ || __IBMCPP__ || 0x5110 <= __SUNPRO_C
 # define _Alignas(a) __attribute__ ((__aligned__ (a)))
 #elif 1300 <= _MSC_VER
 # define _Alignas(a) __declspec ((align (a)))
diff --git a/m4/stdalign.m4 b/m4/stdalign.m4
index d90cee3..da64dc6 100644
--- a/m4/stdalign.m4
+++ b/m4/stdalign.m4
@@ -10,28 +10,13 @@ dnl with or without modifications, as long as this notice 
is preserved.
 AC_DEFUN([gl_STDALIGN_H],
 [
   AC_CHECK_HEADERS_ONCE([stdalign.h])
-  HAVE_ATTRIBUTE_ALIGNED='?'
 
-  if test "$ac_cv_header_stdalign_h" = yes; then
+  if test $ac_cv_header_stdalign_h = yes; then
     STDALIGN_H=''
   else
     STDALIGN_H='stdalign.h'
-    AC_CACHE_CHECK([for  __attribute__ ((__aligned__ (expr)))],
-      [gl_cv_attribute_aligned],
-      [AC_COMPILE_IFELSE(
-         [AC_LANG_PROGRAM(
-            [[char __attribute__ ((__aligned__ (1 << 3))) c;]],
-            [[]])],
-         [gl_cv_attribute_aligned=yes],
-         [gl_cv_attribute_aligned=no])])
-    if test $gl_cv_attribute_aligned = yes; then
-      HAVE_ATTRIBUTE_ALIGNED=1
-    else
-      HAVE_ATTRIBUTE_ALIGNED=0
-    fi
   fi
 
-  AC_SUBST([HAVE_ATTRIBUTE_ALIGNED])
   AC_SUBST([STDALIGN_H])
   AM_CONDITIONAL([GL_GENERATE_STDALIGN_H], [test -n "$STDALIGN_H"])
 ])
diff --git a/modules/stdalign b/modules/stdalign
index 824efbb..c91e5e0 100644
--- a/modules/stdalign
+++ b/modules/stdalign
@@ -19,7 +19,7 @@ if GL_GENERATE_STDALIGN_H
 stdalign.h: stdalign.in.h $(top_builddir)/config.status
        $(AM_V_GEN)rm -f address@hidden $@ && \
        { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-         sed -e 's/@''HAVE_ATTRIBUTE_ALIGNED''@/$(HAVE_ATTRIBUTE_ALIGNED)/g' < 
$(srcdir)/stdalign.in.h; \
+         cat $(srcdir)/stdalign.in.h; \
        } > address@hidden && \
        mv address@hidden $@
 else
diff --git a/tests/test-stdalign.c b/tests/test-stdalign.c
index 136661a..eef9063 100644
--- a/tests/test-stdalign.c
+++ b/tests/test-stdalign.c
@@ -22,6 +22,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <stdlib.h>
 
 #include "verify.h"
 
@@ -41,37 +42,56 @@ verify (__alignas_is_defined == 1);
 # ifndef alignas
 #  error "alignas is not a macro"
 # endif
-# define CHECK_ALIGNAS(type) \
-    type alignas (1 << 3) type##_alignas; \
-    type _Alignas (1 << 3) type##_Alignas;
+# define DECLARE_ALIGNED(type, name) \
+    type alignas (1 << 3) name##_alignas; \
+    type _Alignas (1 << 3) name##_Alignas;
+# define CHECK_ALIGNED(name) \
+    (((uintptr_t) &name##_alignas % (1 << 3) ? abort () : (void) 0), \
+     ((uintptr_t) &name##_Alignas % (1 << 3) ? abort () : (void) 0))
 #else
-# define CHECK_ALIGNAS(type)
+# define DECLARE_ALIGNED(type, name)
+# define CHECK_ALIGNED(name) ((void) 0)
 #endif
 
-#define CHECK(type) \
+#define CHECK_STATIC(type) \
   typedef struct { char slot1; type slot2; } type##_helper; \
   verify (alignof (type) == offsetof (type##_helper, slot2)); \
   verify (_Alignof (type) == alignof (type)); \
   const int type##_alignment = alignof (type); \
-  CHECK_ALIGNAS(type)
-
-CHECK (char)
-CHECK (short)
-CHECK (int)
-CHECK (long)
-CHECK (float)
-CHECK (double)
-CHECK (longdouble)
+  DECLARE_ALIGNED(type, static_##type)
+
+#define CHECK_AUTO(type) \
+  { \
+    DECLARE_ALIGNED(type, auto_##type) \
+    CHECK_ALIGNED(static_##type); \
+    CHECK_ALIGNED(auto_##type); \
+  }
+
 #ifdef INT64_MAX
-CHECK (int64_t)
+# define if_INT64_MAX(x) x
+#else
+# define if_INT64_MAX(x)
 #endif
-CHECK (struct1)
-CHECK (struct2)
-CHECK (struct3)
-CHECK (struct4)
+
+#define CHECK_TYPES(check) \
+  check (char) \
+  check (short) \
+  check (int) \
+  check (long) \
+  if_INT64_MAX (check (int64_t)) \
+  check (float) \
+  check (double) \
+  check (longdouble) \
+  check (struct1) \
+  check (struct2) \
+  check (struct3) \
+  check (struct4)
+
+CHECK_TYPES (CHECK_STATIC)
 
 int
 main ()
 {
+  CHECK_TYPES (CHECK_AUTO)
   return 0;
 }
-- 
1.7.6.4




reply via email to

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