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 <ebl...@redhat.com> 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 +@item +The draft C1X and C++0X @code{static_assert}, and the draft C1X +@code{_Static_assert}, 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 +@item +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>}. +@item +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. +@item +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; \ } > $@-t && \