bug-gnulib
[Top][All Lists]
Advanced

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

Re: proposal: lib/verify.h


From: Paul Eggert
Subject: Re: proposal: lib/verify.h
Date: Mon, 04 Jul 2005 22:25:46 -0700
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Jim Meyering <address@hidden> writes:

>    The implementation uses a struct declaration whose name includes the
>    expansion of __LINE__, so there is a small chance that two uses of
>    verify_decl from different files will end up colliding

I thought about this problem for a bit and came up with a different
implementation where two uses can't possibly collide.  Please see below.

Also, as far as the names of the macros go, I've had second thoughts.
It seems to me that once C99 takes over, "verify_decl" will be the
macro that most people want to use, since you can interleave decls and
statements.  So let's call this macro "verify", and the less-common
expression-oriented macro "verify_expr".  Sorry for whipping you back
and forth about the names.

> # ifndef verify_decl
> #  define GL_CONCAT0(x, y) x##y

How about if we just define GL_CONCAT0 etc. unconditionally?  That's
what other .h files do.  Similarly, we shouldn't need to "#undef
verify".

I installed this patch into coreutils.  Comments?

2005-07-04  Paul Eggert  <address@hidden>

        * lib/verify.h (GL_CONCAT0, GL_CONCAT): Define unconditionally; don't
        depend on whether verify_decl is defined.
        (verify): Renamed from verify_decl.  All uses changed.
        Use an extern function decl, as it can't possibly collide with other
        decls.
        (verify_expr): Renamed from verify.  All uses changed.
        (verify_type__): New private macro.
        (verify, verify_expr): Use it.
        * src/od.c: Adjust to verify.h change.
        * src/system.h (VERIFY_W_TYPEOF): Likewise.

*** lib/verify.h        4 Jul 2005 17:39:48 -0000       1.2
--- lib/verify.h        5 Jul 2005 05:16:08 -0000       1.3
***************
*** 16,43 ****
     along with this program; if not, write to the Free Software Foundation,
     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
  #ifndef VERIFY_H
  # define VERIFY_H 1
  
! # ifndef verify_decl
! #  define GL_CONCAT0(x, y) x##y
! #  define GL_CONCAT(x, y) GL_CONCAT0 (x, y)
! 
! /* Verify requirement, R, at compile-time, as a declaration.
!    The implementation uses a struct declaration whose name includes the
!    expansion of __LINE__, so there is a small chance that two uses of
!    verify_decl from different files will end up colliding (for example,
!    f.c includes f.h and verify_decl is used on the same line in each).  */
! #  define verify_decl(R) \
!     struct GL_CONCAT (ct_assert_, __LINE__) { char a[(R) ? 1 : -1]; }
! # endif
! 
! /* Verify requirement, R, at compile-time, as an expression.
!    Unlike assert, there is no run-time overhead.  Unlike verify_decl,
!    above, there is no risk of collision, since there is no declared name.
!    This macro may be used in some contexts where the other may not, and
!    vice versa.  Return void.  */
! # undef verify
! # define verify(R) ((void) sizeof (struct { char a[(R) ? 1 : -1]; }))
  
  #endif
--- 16,57 ----
     along with this program; if not, write to the Free Software Foundation,
     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
+ /* Written by Paul Eggert and Jim Meyering.  */
+ 
  #ifndef VERIFY_H
  # define VERIFY_H 1
  
! # define GL_CONCAT0(x, y) x##y
! # define GL_CONCAT(x, y) GL_CONCAT0 (x, y)
! 
! /* A type that is valid if and only R is nonzero.
!    R should be an integer constant expression.
!    verify_type__ and verify_error_if_negative_size__ are symbols that
!    are private to this header file.  */
! 
! # define verify_type__(R) \
!     struct { int verify_error_if_negative_size__[(R) ? 1 : -1]; }
! 
! /* Verify requirement R at compile-time, as a declaration.
!    R should be an integer constant expression.
!    Unlike assert, there is no run-time overhead.
! 
!    The implementation uses __LINE__ to lessen the probability of
!    generating a warning that verify_function_NNN is multiply declared.
!    However, even if two declarations in different files have the same
!    __LINE__, the multiple declarations are still valid C89 and C99
!    code because they simply redeclare the same external function, so
!    no conforming compiler will reject them outright.  */
! 
! # define verify(R) \
!     extern verify_type__ (R) GL_CONCAT (verify_function_, __LINE__) (void)
! 
! /* Verify requirement R at compile-time, as an expression.
!    R should be an integer constant expression.
!    Unlike assert, there is no run-time overhead.
!    This macro can be used in some contexts where verify cannot, and vice 
versa.
!    Return void.  */
! 
! # define verify_expr(R) ((void) sizeof (verify_type__ (R)))
  
  #endif
--- src/od.c    4 Jul 2005 17:40:37 -0000       1.162
+++ src/od.c    5 Jul 2005 05:13:47 -0000
@@ -162,7 +162,7 @@ static const int width_bytes[] =
 
 /* Ensure that for each member of `enum size_spec' there is an
    initializer in the width_bytes array.  */
-verify_decl (sizeof width_bytes / sizeof width_bytes[0] == N_SIZE_SPECS);
+verify (sizeof width_bytes / sizeof width_bytes[0] == N_SIZE_SPECS);
 
 /* Names for some non-printing characters.  */
 static const char *const charname[33] =
--- src/system.h        4 Jul 2005 16:06:41 -0000       1.128
+++ src/system.h        5 Jul 2005 05:13:47 -0000
@@ -811,7 +811,7 @@ ptr_align (void const *ptr, size_t align
    TYPEOF_REQUIREMENT is nonzero at compile time.  If the compiler does
    not support __typeof__, do nothing.  */
 #if HAVE_TYPEOF
-# define VERIFY_W_TYPEOF(typeof_requirement) verify (typeof_requirement)
+# define VERIFY_W_TYPEOF(typeof_requirement) verify_expr (typeof_requirement)
 #else
 # define VERIFY_W_TYPEOF(typeof_requirement) ((void) 0)
 #endif




reply via email to

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