bug-gnulib
[Top][All Lists]
Advanced

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

Re: [bug-gnulib] Re: [bug-gnulib] Re: new gnulib module "verify" for com


From: Paul Eggert
Subject: Re: [bug-gnulib] Re: [bug-gnulib] Re: new gnulib module "verify" for compile-time assertions
Date: Mon, 26 Sep 2005 11:02:10 -0700
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Bruno Haible <address@hidden> writes:

> Now one more simplification is possible: A variable declaration does it
> just as nicely as a function declaration.

But gcc -Wall warns about unused variables, even if they're extern.
If we used a variable declaration, then

  #include <verify.h>
  int main (void) { verify (1 + 1 == 2); return 0; }

would cause gcc -Wall to report something like this:

  t.c: In function 'main':
  t.c:2: warning: unused variable 'verify_variable__'


I have a different idea: replace verify_expr(R) with a new macro
verify_true(R) that acts like verify_expr(R), but is an integer
constant expression that always yields true.  The advantage of
verify_true(R) is that it can be used in contexts where verify_expr(R)
cannot (e.g., the initializer of an enum).

Here is a proposed patch (I haven't installed it).

2005-09-26  Paul Eggert  <address@hidden>

        * verify.h (verify_expr): Remove, replacing with:
        (verify_true): New macro that returns true instead of void.
        (verify_type__): Remove.
        (verify): Use verify_true rather than verify_type__.

*** old/verify.h        Fri Sep 23 15:59:59 2005
--- new/verify.h        Mon Sep 26 10:57:51 2005
***************
*** 23,46 ****
  
  /* Each of these macros verifies that its argument R is a nonzero
     constant expression.  To be portable, R's type must be integer (or
!    boolean).  Unlike assert, there is no run-time overhead.  */
  
! /* A type that is valid if and only if R is a nonzero constant expression.
!    The symbols verify_type__ and verify_error_if_negative_size__ are
!    private to this header file.  */
  
! # define verify_type__(R) \
!     struct { unsigned int verify_error_if_negative_size__ : (R) ? 1 : -1; }
  
! /* Verify requirement R at compile-time, as a declaration.  */
  
! # define verify(R) \
!     extern int (* verify_function__ (void)) [sizeof (verify_type__ (R))]
  
! /* Verify requirement R at compile-time, as an expression.
!    This macro can be used in some contexts where verify cannot, and vice 
versa.
!    Return void.  */
  
! # define verify_expr(R) ((void) ((verify_type__ (R) *) 0))
  
  #endif
--- 23,48 ----
  
  /* Each of these macros verifies that its argument R is a nonzero
     constant expression.  To be portable, R's type must be integer (or
!    boolean).  Unlike assert, there is no run-time overhead.
  
!    There are two macros, since no single macro can be used in all
!    contexts in C.  verify_true (R) is for scalar contexts, where it
!    may be cast to void if need be.  verify (R) is for declaration
!    contexts, e.g., the top level.
  
!    The symbols verify_error_if_negative_size__ and verify_function__
!    are private to this header.  */
  
! /* Verify requirement R at compile-time, as an integer constant expression.
!    Return true.  */
  
! # define verify_true(R) \
!     (!!sizeof \
!      (struct { unsigned int verify_error_if_negative_size__ : (R) ? 1 : -1; 
}))
  
! /* Verify requirement R at compile-time, as a declaration without a
!    trailing ';'.  */
  
! # define verify(R) extern int (* verify_function__ (void)) [verify_true (R)]
  
  #endif




reply via email to

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