Annotation of embedaddon/libiconv/srclib/verify.h, revision 1.1
1.1 ! misho 1: /* Compile-time assert-like macros.
! 2:
! 3: Copyright (C) 2005-2006, 2009-2011 Free Software Foundation, Inc.
! 4:
! 5: This program is free software: you can redistribute it and/or modify
! 6: it under the terms of the GNU General Public License as published by
! 7: the Free Software Foundation; either version 3 of the License, or
! 8: (at your option) any later version.
! 9:
! 10: This program is distributed in the hope that it will be useful,
! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 13: GNU General Public License for more details.
! 14:
! 15: You should have received a copy of the GNU General Public License
! 16: along with this program. If not, see <http://www.gnu.org/licenses/>. */
! 17:
! 18: /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
! 19:
! 20: #ifndef _GL_VERIFY_H
! 21: # define _GL_VERIFY_H
! 22:
! 23:
! 24: /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the
! 25: C1X draft N1548 section 6.7.10. This is supported by GCC 4.6.0 and
! 26: later, in C mode, and its use here generates easier-to-read diagnostics
! 27: when verify (R) fails.
! 28:
! 29: Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per the
! 30: C++0X draft N3242 section 7.(4).
! 31: This will likely be supported by future GCC versions, in C++ mode.
! 32:
! 33: Use this only with GCC. If we were willing to slow 'configure'
! 34: down we could also use it with other compilers, but since this
! 35: affects only the quality of diagnostics, why bother? */
! 36: # if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus
! 37: # define _GL_HAVE__STATIC_ASSERT 1
! 38: # endif
! 39: /* The condition (99 < __GNUC__) is temporary, until we know about the
! 40: first G++ release that supports static_assert. */
! 41: # if (99 < __GNUC__) && defined __cplusplus
! 42: # define _GL_HAVE_STATIC_ASSERT 1
! 43: # endif
! 44:
! 45: /* Each of these macros verifies that its argument R is nonzero. To
! 46: be portable, R should be an integer constant expression. Unlike
! 47: assert (R), there is no run-time overhead.
! 48:
! 49: If _Static_assert works, verify (R) uses it directly. Similarly,
! 50: _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct
! 51: that is an operand of sizeof.
! 52:
! 53: The code below uses several ideas for C++ compilers, and for C
! 54: compilers that do not support _Static_assert:
! 55:
! 56: * The first step is ((R) ? 1 : -1). Given an expression R, of
! 57: integral or boolean or floating-point type, this yields an
! 58: expression of integral type, whose value is later verified to be
! 59: constant and nonnegative.
! 60:
! 61: * Next this expression W is wrapped in a type
! 62: struct _gl_verify_type {
! 63: unsigned int _gl_verify_error_if_negative: W;
! 64: }.
! 65: If W is negative, this yields a compile-time error. No compiler can
! 66: deal with a bit-field of negative size.
! 67:
! 68: One might think that an array size check would have the same
! 69: effect, that is, that the type struct { unsigned int dummy[W]; }
! 70: would work as well. However, inside a function, some compilers
! 71: (such as C++ compilers and GNU C) allow local parameters and
! 72: variables inside array size expressions. With these compilers,
! 73: an array size check would not properly diagnose this misuse of
! 74: the verify macro:
! 75:
! 76: void function (int n) { verify (n < 0); }
! 77:
! 78: * For the verify macro, the struct _gl_verify_type will need to
! 79: somehow be embedded into a declaration. To be portable, this
! 80: declaration must declare an object, a constant, a function, or a
! 81: typedef name. If the declared entity uses the type directly,
! 82: such as in
! 83:
! 84: struct dummy {...};
! 85: typedef struct {...} dummy;
! 86: extern struct {...} *dummy;
! 87: extern void dummy (struct {...} *);
! 88: extern struct {...} *dummy (void);
! 89:
! 90: two uses of the verify macro would yield colliding declarations
! 91: if the entity names are not disambiguated. A workaround is to
! 92: attach the current line number to the entity name:
! 93:
! 94: #define _GL_CONCAT0(x, y) x##y
! 95: #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
! 96: extern struct {...} * _GL_CONCAT (dummy, __LINE__);
! 97:
! 98: But this has the problem that two invocations of verify from
! 99: within the same macro would collide, since the __LINE__ value
! 100: would be the same for both invocations. (The GCC __COUNTER__
! 101: macro solves this problem, but is not portable.)
! 102:
! 103: A solution is to use the sizeof operator. It yields a number,
! 104: getting rid of the identity of the type. Declarations like
! 105:
! 106: extern int dummy [sizeof (struct {...})];
! 107: extern void dummy (int [sizeof (struct {...})]);
! 108: extern int (*dummy (void)) [sizeof (struct {...})];
! 109:
! 110: can be repeated.
! 111:
! 112: * Should the implementation use a named struct or an unnamed struct?
! 113: Which of the following alternatives can be used?
! 114:
! 115: extern int dummy [sizeof (struct {...})];
! 116: extern int dummy [sizeof (struct _gl_verify_type {...})];
! 117: extern void dummy (int [sizeof (struct {...})]);
! 118: extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
! 119: extern int (*dummy (void)) [sizeof (struct {...})];
! 120: extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
! 121:
! 122: In the second and sixth case, the struct type is exported to the
! 123: outer scope; two such declarations therefore collide. GCC warns
! 124: about the first, third, and fourth cases. So the only remaining
! 125: possibility is the fifth case:
! 126:
! 127: extern int (*dummy (void)) [sizeof (struct {...})];
! 128:
! 129: * GCC warns about duplicate declarations of the dummy function if
! 130: -Wredundant_decls is used. GCC 4.3 and later have a builtin
! 131: __COUNTER__ macro that can let us generate unique identifiers for
! 132: each dummy function, to suppress this warning.
! 133:
! 134: * This implementation exploits the fact that older versions of GCC,
! 135: which do not support _Static_assert, also do not warn about the
! 136: last declaration mentioned above.
! 137:
! 138: * In C++, any struct definition inside sizeof is invalid.
! 139: Use a template type to work around the problem. */
! 140:
! 141: /* Concatenate two preprocessor tokens. */
! 142: # define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
! 143: # define _GL_CONCAT0(x, y) x##y
! 144:
! 145: /* _GL_COUNTER is an integer, preferably one that changes each time we
! 146: use it. Use __COUNTER__ if it works, falling back on __LINE__
! 147: otherwise. __LINE__ isn't perfect, but it's better than a
! 148: constant. */
! 149: # if defined __COUNTER__ && __COUNTER__ != __COUNTER__
! 150: # define _GL_COUNTER __COUNTER__
! 151: # else
! 152: # define _GL_COUNTER __LINE__
! 153: # endif
! 154:
! 155: /* Generate a symbol with the given prefix, making it unique if
! 156: possible. */
! 157: # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
! 158:
! 159: /* Verify requirement R at compile-time, as an integer constant expression
! 160: that returns 1. If R is false, fail at compile-time, preferably
! 161: with a diagnostic that includes the string-literal DIAGNOSTIC. */
! 162:
! 163: # define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
! 164: (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
! 165:
! 166: # ifdef __cplusplus
! 167: # if !GNULIB_defined_struct__gl_verify_type
! 168: template <int w>
! 169: struct _gl_verify_type {
! 170: unsigned int _gl_verify_error_if_negative: w;
! 171: };
! 172: # define GNULIB_defined_struct__gl_verify_type 1
! 173: # endif
! 174: # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
! 175: _gl_verify_type<(R) ? 1 : -1>
! 176: # elif defined _GL_HAVE__STATIC_ASSERT
! 177: # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
! 178: struct { \
! 179: _Static_assert (R, DIAGNOSTIC); \
! 180: int _gl_dummy; \
! 181: }
! 182: # else
! 183: # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
! 184: struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
! 185: # endif
! 186:
! 187: /* Verify requirement R at compile-time, as a declaration without a
! 188: trailing ';'. If R is false, fail at compile-time, preferably
! 189: with a diagnostic that includes the string-literal DIAGNOSTIC.
! 190:
! 191: Unfortunately, unlike C1X, this implementation must appear as an
! 192: ordinary declaration, and cannot appear inside struct { ... }. */
! 193:
! 194: # ifdef _GL_HAVE__STATIC_ASSERT
! 195: # define _GL_VERIFY _Static_assert
! 196: # else
! 197: # define _GL_VERIFY(R, DIAGNOSTIC) \
! 198: extern int (*_GL_GENSYM (_gl_verify_function) (void)) \
! 199: [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
! 200: # endif
! 201:
! 202: /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */
! 203: # ifdef _GL_STATIC_ASSERT_H
! 204: # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert
! 205: # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
! 206: # endif
! 207: # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert
! 208: # define static_assert _Static_assert /* Draft C1X requires this #define. */
! 209: # endif
! 210: # endif
! 211:
! 212: /* @assert.h omit start@ */
! 213:
! 214: /* Each of these macros verifies that its argument R is nonzero. To
! 215: be portable, R should be an integer constant expression. Unlike
! 216: assert (R), there is no run-time overhead.
! 217:
! 218: There are two macros, since no single macro can be used in all
! 219: contexts in C. verify_true (R) is for scalar contexts, including
! 220: integer constant expression contexts. verify (R) is for declaration
! 221: contexts, e.g., the top level. */
! 222:
! 223: /* Verify requirement R at compile-time, as an integer constant expression.
! 224: Return 1. This is equivalent to verify_expr (R, 1).
! 225:
! 226: verify_true is obsolescent; please use verify_expr instead. */
! 227:
! 228: # define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")")
! 229:
! 230: /* Verify requirement R at compile-time. Return the value of the
! 231: expression E. */
! 232:
! 233: # define verify_expr(R, E) \
! 234: (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))
! 235:
! 236: /* Verify requirement R at compile-time, as a declaration without a
! 237: trailing ';'. */
! 238:
! 239: # define verify(R) _GL_VERIFY (R, "verify (" #R ")")
! 240:
! 241: /* @assert.h omit end@ */
! 242:
! 243: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>