X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fverify.h;h=328980fa362917971489b059236f60349bd09c3f;hb=fb84631f1ec8e82d252cbad0b5b7f83a98e74ba9;hp=c755762aa3685e36a065ed7f9cdb8ed3a48ab687;hpb=ad97909ae566154c082b116ad88c1ab82ec26291;p=gnulib.git diff --git a/lib/verify.h b/lib/verify.h index c755762aa..328980fa3 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -21,37 +21,35 @@ #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 if 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) ((verify_type__ (R) *) 0)) +/* 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. */ + +# ifdef __cplusplus +template + struct verify_type__ { unsigned int verify_error_if_negative_size__: w; }; +# define verify_true(R) \ + (!!sizeof (verify_type__<(R) ? 1 : -1>)) +# else +# define verify_true(R) \ + (!!sizeof \ + (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; })) +# endif + +/* Verify requirement R at compile-time, as a declaration without a + trailing ';'. */ + +# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)] #endif