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>