bug-gnulib
[Top][All Lists]
Advanced

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

Re: [PATCH] verify: use _Static_assert if available


From: Bruno Haible
Subject: Re: [PATCH] verify: use _Static_assert if available
Date: Fri, 8 Apr 2011 21:30:10 +0200
User-agent: KMail/1.9.9

Pádraig Brady wrote:
> So C++0x support in gcc 4.6.0 is using static_assert()
> while C1X support is using _Static_assert().

ISO C1X draft n1548 [1] defines _Static_assert as a keyword (A.1.2).
The meaning of _Static_assert is defined in section 6.7.10:

  6.7.10 Static assertions

  Syntax

       static_assert-declaration:
                _Static_assert ( constant-expression , string-literal ) ;

  Constraints

  The constant expression shall compare unequal to 0.

  Semantics

  The constant expression shall be an integer constant expression. If the value 
of the
  constant expression compares unequal to 0, the declaration has no effect. 
Otherwise, the
  constraint is violated and the implementation shall produce a diagnostic 
message that
  includes the text of the string literal, except that characters not in the 
basic source
  character set are not required to appear in the message.

And finally in 7.2 Diagnostics <assert.h>:

  The macro
        static_assert
  expands to _Static_assert.

On the other hand, ISO C++ draft n3242 defines static_assert as a keyword 
(2.13),
and the meaning is defined in 7.(4):

  In a static_assert-declaration the constant-expression shall be a constant
  expression (5.19) that can be contextually converted to bool (Clause 4). If
  the value of the expression when so converted is true, the declaration has
  no effect. Otherwise, the program is ill-formed, and the resulting diagnostic
  message (1.4) shall include the text of the string-literal, except that
  characters not in the basic source character set (2.3) are not required to
  appear in the diagnostic message. [ Example:
    static_assert(sizeof(long) >= 8, "64-bit code generation required for this 
library.");
  — end example ]

Such a static_assert-declaration is allowed in a block and also as a
member-declaration in a struct or class.

[1] http://www.open-std.org/Jtc1/sc22/wg14/www/docs/n1548.pdf
[2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf

> Why the divergence in the standards?

It's like with 'bool'. In the ISO C standard, they appear to prefer to not
introduce new keywords that don't start with '_'.

But you have a point: Paul's patch does not work with GCC 4.6.0 in C++ mode.

$ cat foo.c
#include "verify.h"
verify (sizeof (long) > 1);
$ /arch/x86-linux/gnu-inst-gcc/4.5.2/bin/gcc -I lib -S foo.c
$ /arch/x86-linux/gnu-inst-gcc/4.6.0/bin/gcc -I lib -S foo.c
$ ln foo.c foo.cc
$ /arch/x86-linux/gnu-inst-gcc/4.5.2/bin/gcc -I lib -S foo.cc
$ /arch/x86-linux/gnu-inst-gcc/4.6.0/bin/gcc -I lib -S foo.cc
foo.cc:3:1: error: expected constructor, destructor, or type conversion before 
'(' token

Here's a proposed patch to fix it.


2011-04-08  Bruno Haible  <address@hidden>

        verify: Fix syntax error with GCC 4.6 in C++ mode.
        * lib/verify.h (HAVE__STATIC_ASSERT): Don't define in C++ mode.
        (HAVE_STATIC_ASSERT): New macro.
        (verify_true, verify): Use 'static_assert' if it is supported and
        '_Static_assert' is not supported.

--- lib/verify.h.orig   Fri Apr  8 21:26:22 2011
+++ lib/verify.h        Fri Apr  8 21:25:00 2011
@@ -22,14 +22,21 @@
 
 /* Define HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the
    C1X draft N1548 section 6.7.10.  This is supported by GCC 4.6.0 and
-   later, and its use here generates easier-to-read diagnostics when
-   verify (R) fails.
+   later, in C mode, and its use here generates easier-to-read diagnostics
+   when verify (R) fails.
+
+   Define HAVE_STATIC_ASSERT to 1 if static_assert works as per the
+   C1X draft N1548 section 7.2 or the C++0X draft N3242 section 7.(4).
+   This will likely be supported by future GCC versions, in C++ mode.
 
    For now, use this only with GCC.  Eventually whether _Static_assert
-   works should be determined by 'configure'.  */
-# if 4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)
+   and static_assert works should be determined by 'configure'.  */
+# if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined 
__cplusplus
 #  define HAVE__STATIC_ASSERT 1
 # endif
+# if 0 && defined __cplusplus
+#  define HAVE_STATIC_ASSERT 1
+# endif
 
 /* Each of these macros verifies that its argument R is nonzero.  To
    be portable, R should be an integer constant expression.  Unlike
@@ -165,6 +172,13 @@
         _Static_assert (R, "verify_true (" #R ")"); \
         int verify_dummy__; \
        }))
+# elif HAVE_STATIC_ASSERT
+#  define verify_true(R) \
+     (!!sizeof \
+      (struct { \
+        static_assert (R, "verify_true (" #R ")"); \
+        int verify_dummy__; \
+       }))
 # else
 #  define verify_true(R) \
      (!!sizeof \
@@ -176,6 +190,8 @@
 
 # if HAVE__STATIC_ASSERT
 #  define verify(R) _Static_assert (R, "verify (" #R ")")
+# elif HAVE_STATIC_ASSERT
+#  define verify(R) static_assert (R, "verify (" #R ")")
 # else
 #  define verify(R) \
     extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)]
-- 
In memoriam Hans von Dohnanyi <http://en.wikipedia.org/wiki/Hans_von_Dohnanyi>



reply via email to

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