bug-gnulib
[Top][All Lists]
Advanced

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

Re: proposed support for C1X-style static_assert


From: Paul Eggert
Subject: Re: proposed support for C1X-style static_assert
Date: Thu, 05 May 2011 10:15:11 -0700
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110421 Fedora/3.1.9-2.fc14 Thunderbird/3.1.9

On 05/05/11 01:10, Bruno Haible wrote:
> - A doc update of doc/posix-headers/assert.texi would be useful.

Thanks for catching that.  A further draft patch is below.  It also
notes a minor difference between C89 and C99 'assert'.

>   Identifiers starting with __ are in the namespace of compiler and libc
>   implementation.

Identifiers starting with "_G" are also reserved, and we usurp them,
so I figured we should usurp "__gl_" to be consistent.  It's no big
deal, I'll change the __gl_ prefix to a _gl_ prefix.  But strictly
speaking, as far as I can see, the following code conforms to draft
C1X:

     #define _gl_static_assert_error_if_negative 100
     #include <assert.h>
     static_assert (1);

and once we change __gl_ to _gl_ this (perverse) code won't work any more.

> - Can the new static_assert be used in an ISO C++ compatible way [1], that is,
>   as a member declaration in a struct or class?

Unfortunately not.  I noted that in the documentation proposed below.

diff --git a/ChangeLog b/ChangeLog
index 24dd572..4028ea1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,7 @@
        and _Static_assert is not built in.
        (verify_true, verify): Define only if _GL_STATIC_ASSERT_H is not
        defined, and use the new macros mentioned above.
+       * doc/posix-headers/assert.texi: Document this
 
 2011-05-05  Eric Blake  <address@hidden>
 
diff --git a/doc/posix-headers/assert.texi b/doc/posix-headers/assert.texi
index 02a1c3b..aa78ee7 100644
--- a/doc/posix-headers/assert.texi
+++ b/doc/posix-headers/assert.texi
@@ -3,12 +3,31 @@
 
 POSIX specification:@* 
@url{http://www.opengroup.org/onlinepubs/9699919799/basedefs/assert.h.html}
 
-Gnulib module: ---
+Gnulib module: assert-h
+
+See also the Gnulib module @code{assert}.
 
 Portability problems fixed by Gnulib:
 @itemize
address@hidden
+The draft C1X and C++0X @code{static_assert}, and the draft C1X
address@hidden, are not supported by many platforms.
+For example, GCC versions before 4.6.0 do not support @code{_Static_assert},
+and G++ versions through at least 4.6.0 do not support @code{static_assert}.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
address@hidden
+Draft C1X @code{_Static_assert} and draft C++0X @code{static_assert}
+are keywords that can be used without including @code{<assert.h>}.
+The Gnulib substitutes are macros that require including @code{<assert.h>}.
address@hidden
+The draft C1X @code{static_assert} and @code{_Static_assert} can also
+be used within a @code{struct} or @code{union} specifier, in place of
+an ordinary declaration of a member of the struct or union.  The
+Gnulib substitute can be used only as an ordinary declaration.
address@hidden
+In C99, @code{assert} can be applied to any scalar expression.
+In C89, the argument to @code{assert} is of type @code{int}.
 @end itemize
diff --git a/lib/verify.h b/lib/verify.h
index 39a5ffc..e5065ff 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -59,8 +59,8 @@
      constant and nonnegative.
 
    * Next this expression W is wrapped in a type
-     struct __gl_verify_type {
-       unsigned int __gl_verify_error_if_negative: W;
+     struct _gl_verify_type {
+       unsigned int _gl_verify_error_if_negative: W;
      }.
      If W is negative, this yields a compile-time error.  No compiler can
      deal with a bit-field of negative size.
@@ -75,7 +75,7 @@
 
        void function (int n) { verify (n < 0); }
 
-   * For the verify macro, the struct __gl_verify_type will need to
+   * For the verify macro, the struct _gl_verify_type will need to
      somehow be embedded into a declaration.  To be portable, this
      declaration must declare an object, a constant, a function, or a
      typedef name.  If the declared entity uses the type directly,
@@ -113,11 +113,11 @@
      Which of the following alternatives can be used?
 
        extern int dummy [sizeof (struct {...})];
-       extern int dummy [sizeof (struct __gl_verify_type {...})];
+       extern int dummy [sizeof (struct _gl_verify_type {...})];
        extern void dummy (int [sizeof (struct {...})]);
-       extern void dummy (int [sizeof (struct __gl_verify_type {...})]);
+       extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
        extern int (*dummy (void)) [sizeof (struct {...})];
-       extern int (*dummy (void)) [sizeof (struct __gl_verify_type {...})];
+       extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
 
      In the second and sixth case, the struct type is exported to the
      outer scope; two such declarations therefore collide.  GCC warns
@@ -165,20 +165,20 @@
 
 # ifdef __cplusplus
 template <int w>
-  struct __gl_verify_type {
-    unsigned int __gl_verify_error_if_negative: w;
+  struct _gl_verify_type {
+    unsigned int _gl_verify_error_if_negative: w;
   };
 #  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
-    __gl_verify_type<(R) ? 1 : -1>
+    _gl_verify_type<(R) ? 1 : -1>
 # elif defined _GL_HAVE__STATIC_ASSERT
 #  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
      struct {                                   \
        _Static_assert (R, DIAGNOSTIC);          \
-       int __gl_dummy;                          \
+       int _gl_dummy;                          \
      }
 # else
 #  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
-     struct { unsigned int __gl_verify_error_if_negative: (R) ? 1 : -1; }
+     struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
 # endif
 
 /* Verify requirement R at compile-time, as a declaration without a
@@ -192,17 +192,17 @@ template <int w>
 #  define _GL_VERIFY _Static_assert
 # else
 #  define _GL_VERIFY(R, DIAGNOSTIC)                                   \
-     extern int (*_GL_GENSYM (__gl_verify_function) (void))           \
+     extern int (*_GL_GENSYM (_gl_verify_function) (void))            \
        [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
 # endif
 
 /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h.  */
 # ifdef _GL_STATIC_ASSERT_H
+#  if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert
+#   define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
+#  endif
 #  if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert
 #   define static_assert _Static_assert /* Draft C1X requires this #define.  */
-#   ifndef _GL_HAVE__STATIC_ASSERT
-#    define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
-#   endif
 #  endif
 # else
 
diff --git a/modules/assert-h b/modules/assert-h
index eeda888..50bd9f8 100644
--- a/modules/assert-h
+++ b/modules/assert-h
@@ -26,7 +26,7 @@ assert.h: assert.in.h verify.h $(top_builddir)/config.status
              -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
              -e 's|@''NEXT_ASSERT_H''@|$(NEXT_ASSERT_H)|g' \
              < $(srcdir)/assert.in.h && \
-         sed -e 's|__gl_verify|__gl_static_assert|g' \
+         sed -e 's|_gl_verify|_gl_static_assert|g' \
              -e 's|_GL_VERIFY|_GL_STATIC_ASSERT|g' \
              < $(srcdir)/verify.h; \
        } > address@hidden && \




reply via email to

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