File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / srclib / verify.h
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue May 29 09:29:43 2012 UTC (12 years, 1 month ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>