verify.h 9.59 KB
Newer Older
1 2
/* Compile-time assert-like macros.

3
   Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
#ifndef _GL_VERIFY_H
# define _GL_VERIFY_H


/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11.
   This is supported by GCC 4.6.0 and later, in C mode, and its use
   here generates easier-to-read diagnostics when verify (R) fails.

   Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11.
   This will likely be supported by future GCC versions, in C++ mode.

   Use this only with GCC.  If we were willing to slow 'configure'
   down we could also use it with other compilers, but since this
   affects only the quality of diagnostics, why bother?  */
# if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus
#  define _GL_HAVE__STATIC_ASSERT 1
# endif
/* The condition (99 < __GNUC__) is temporary, until we know about the
   first G++ release that supports static_assert.  */
# if (99 < __GNUC__) && defined __cplusplus
#  define _GL_HAVE_STATIC_ASSERT 1
# endif
42 43 44 45 46

/* Each of these macros verifies that its argument R is nonzero.  To
   be portable, R should be an integer constant expression.  Unlike
   assert (R), there is no run-time overhead.

47 48 49
   If _Static_assert works, verify (R) uses it directly.  Similarly,
   _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct
   that is an operand of sizeof.
50

51 52
   The code below uses several ideas for C++ compilers, and for C
   compilers that do not support _Static_assert:
53 54 55 56 57 58 59

   * The first step is ((R) ? 1 : -1).  Given an expression R, of
     integral or boolean or floating-point type, this yields an
     expression of integral type, whose value is later verified to be
     constant and nonnegative.

   * Next this expression W is wrapped in a type
60 61 62
     struct _gl_verify_type {
       unsigned int _gl_verify_error_if_negative: W;
     }.
63 64 65 66 67 68 69 70 71 72 73 74 75
     If W is negative, this yields a compile-time error.  No compiler can
     deal with a bit-field of negative size.

     One might think that an array size check would have the same
     effect, that is, that the type struct { unsigned int dummy[W]; }
     would work as well.  However, inside a function, some compilers
     (such as C++ compilers and GNU C) allow local parameters and
     variables inside array size expressions.  With these compilers,
     an array size check would not properly diagnose this misuse of
     the verify macro:

       void function (int n) { verify (n < 0); }

76
   * For the verify macro, the struct _gl_verify_type will need to
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
     somehow be embedded into a declaration.  To be portable, this
     declaration must declare an object, a constant, a function, or a
     typedef name.  If the declared entity uses the type directly,
     such as in

       struct dummy {...};
       typedef struct {...} dummy;
       extern struct {...} *dummy;
       extern void dummy (struct {...} *);
       extern struct {...} *dummy (void);

     two uses of the verify macro would yield colliding declarations
     if the entity names are not disambiguated.  A workaround is to
     attach the current line number to the entity name:

       #define _GL_CONCAT0(x, y) x##y
       #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
       extern struct {...} * _GL_CONCAT (dummy, __LINE__);

     But this has the problem that two invocations of verify from
     within the same macro would collide, since the __LINE__ value
     would be the same for both invocations.  (The GCC __COUNTER__
     macro solves this problem, but is not portable.)

     A solution is to use the sizeof operator.  It yields a number,
     getting rid of the identity of the type.  Declarations like

       extern int dummy [sizeof (struct {...})];
       extern void dummy (int [sizeof (struct {...})]);
       extern int (*dummy (void)) [sizeof (struct {...})];

     can be repeated.

   * Should the implementation use a named struct or an unnamed struct?
     Which of the following alternatives can be used?

       extern int dummy [sizeof (struct {...})];
114
       extern int dummy [sizeof (struct _gl_verify_type {...})];
115
       extern void dummy (int [sizeof (struct {...})]);
116
       extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
117
       extern int (*dummy (void)) [sizeof (struct {...})];
118
       extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
119 120 121 122 123 124 125 126 127

     In the second and sixth case, the struct type is exported to the
     outer scope; two such declarations therefore collide.  GCC warns
     about the first, third, and fourth cases.  So the only remaining
     possibility is the fifth case:

       extern int (*dummy (void)) [sizeof (struct {...})];

   * GCC warns about duplicate declarations of the dummy function if
128
     -Wredundant-decls is used.  GCC 4.3 and later have a builtin
129 130 131
     __COUNTER__ macro that can let us generate unique identifiers for
     each dummy function, to suppress this warning.

132 133 134
   * This implementation exploits the fact that older versions of GCC,
     which do not support _Static_assert, also do not warn about the
     last declaration mentioned above.
135

136 137 138
   * GCC warns if -Wnested-externs is enabled and verify() is used
     within a function body; but inside a function, you can always
     arrange to use verify_expr() instead.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

   * In C++, any struct definition inside sizeof is invalid.
     Use a template type to work around the problem.  */

/* Concatenate two preprocessor tokens.  */
# define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
# define _GL_CONCAT0(x, y) x##y

/* _GL_COUNTER is an integer, preferably one that changes each time we
   use it.  Use __COUNTER__ if it works, falling back on __LINE__
   otherwise.  __LINE__ isn't perfect, but it's better than a
   constant.  */
# if defined __COUNTER__ && __COUNTER__ != __COUNTER__
#  define _GL_COUNTER __COUNTER__
# else
#  define _GL_COUNTER __LINE__
# endif

/* Generate a symbol with the given prefix, making it unique if
   possible.  */
# define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)

161 162 163 164 165 166
/* Verify requirement R at compile-time, as an integer constant expression
   that returns 1.  If R is false, fail at compile-time, preferably
   with a diagnostic that includes the string-literal DIAGNOSTIC.  */

# define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
    (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
167 168

# ifdef __cplusplus
169
#  if !GNULIB_defined_struct__gl_verify_type
170
template <int w>
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
  struct _gl_verify_type {
    unsigned int _gl_verify_error_if_negative: w;
  };
#   define GNULIB_defined_struct__gl_verify_type 1
#  endif
#  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
    _gl_verify_type<(R) ? 1 : -1>
# elif defined _GL_HAVE__STATIC_ASSERT
#  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
     struct {                                   \
       _Static_assert (R, DIAGNOSTIC);          \
       int _gl_dummy;                          \
     }
# else
#  define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
     struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
# endif

/* Verify requirement R at compile-time, as a declaration without a
   trailing ';'.  If R is false, fail at compile-time, preferably
   with a diagnostic that includes the string-literal DIAGNOSTIC.

   Unfortunately, unlike C11, this implementation must appear as an
   ordinary declaration, and cannot appear inside struct { ... }.  */

# ifdef _GL_HAVE__STATIC_ASSERT
#  define _GL_VERIFY _Static_assert
198
# else
199 200 201
#  define _GL_VERIFY(R, DIAGNOSTIC)				       \
     extern int (*_GL_GENSYM (_gl_verify_function) (void))	       \
       [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
202 203
# endif

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h.  */
# ifdef _GL_STATIC_ASSERT_H
#  if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert
#   define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
#  endif
#  if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert
#   define static_assert _Static_assert /* C11 requires this #define.  */
#  endif
# endif

/* @assert.h omit start@  */

/* Each of these macros verifies that its argument R is nonzero.  To
   be portable, R should be an integer constant expression.  Unlike
   assert (R), 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, including
   integer constant expression contexts.  verify (R) is for declaration
   contexts, e.g., the top level.  */

/* Verify requirement R at compile-time, as an integer constant expression.
   Return 1.  This is equivalent to verify_expr (R, 1).

   verify_true is obsolescent; please use verify_expr instead.  */

# define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")")

/* Verify requirement R at compile-time.  Return the value of the
   expression E.  */

# define verify_expr(R, E) \
    (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))

238 239 240
/* Verify requirement R at compile-time, as a declaration without a
   trailing ';'.  */

241 242 243
# define verify(R) _GL_VERIFY (R, "verify (" #R ")")

/* @assert.h omit end@  */
244 245

#endif