[Top][All Lists]
[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>