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 <br...@clisp.org> 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>