9fa5111b6e8dd04775c7c1506a907880903dc395
[bpt/guile.git] / lib / verify.h
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 Lesser 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 VERIFY_H
21 # define VERIFY_H 1
22
23 /* Define HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the
24 C1X draft N1548 section 6.7.10. This is supported by GCC 4.6.0 and
25 later, in C mode, and its use here generates easier-to-read diagnostics
26 when verify (R) fails.
27
28 Define HAVE_STATIC_ASSERT to 1 if static_assert works as per the
29 C1X draft N1548 section 7.2 or the C++0X draft N3242 section 7.(4).
30 This will likely be supported by future GCC versions, in C++ mode.
31
32 For now, use this only with GCC. Eventually whether _Static_assert
33 and static_assert works should be determined by 'configure'. */
34 # if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus
35 # define HAVE__STATIC_ASSERT 1
36 # endif
37 /* The condition (99 < __GNUC__) is temporary, until we know about the
38 first G++ release that supports static_assert. */
39 # if (99 < __GNUC__) && defined __cplusplus
40 # define HAVE_STATIC_ASSERT 1
41 # endif
42
43 /* Each of these macros verifies that its argument R is nonzero. To
44 be portable, R should be an integer constant expression. Unlike
45 assert (R), there is no run-time overhead.
46
47 There are two macros, since no single macro can be used in all
48 contexts in C. verify_true (R) is for scalar contexts, including
49 integer constant expression contexts. verify (R) is for declaration
50 contexts, e.g., the top level.
51
52 Symbols ending in "__" are private to this header.
53
54 If _Static_assert works, verify (R) uses it directly. Similarly,
55 verify_true (R) works by packaging a _Static_assert inside a struct
56 that is an operand of sizeof.
57
58 The code below uses several ideas for C++ compilers, and for C
59 compilers that do not support _Static_assert:
60
61 * The first step is ((R) ? 1 : -1). Given an expression R, of
62 integral or boolean or floating-point type, this yields an
63 expression of integral type, whose value is later verified to be
64 constant and nonnegative.
65
66 * Next this expression W is wrapped in a type
67 struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }.
68 If W is negative, this yields a compile-time error. No compiler can
69 deal with a bit-field of negative size.
70
71 One might think that an array size check would have the same
72 effect, that is, that the type struct { unsigned int dummy[W]; }
73 would work as well. However, inside a function, some compilers
74 (such as C++ compilers and GNU C) allow local parameters and
75 variables inside array size expressions. With these compilers,
76 an array size check would not properly diagnose this misuse of
77 the verify macro:
78
79 void function (int n) { verify (n < 0); }
80
81 * For the verify macro, the struct verify_type__ will need to
82 somehow be embedded into a declaration. To be portable, this
83 declaration must declare an object, a constant, a function, or a
84 typedef name. If the declared entity uses the type directly,
85 such as in
86
87 struct dummy {...};
88 typedef struct {...} dummy;
89 extern struct {...} *dummy;
90 extern void dummy (struct {...} *);
91 extern struct {...} *dummy (void);
92
93 two uses of the verify macro would yield colliding declarations
94 if the entity names are not disambiguated. A workaround is to
95 attach the current line number to the entity name:
96
97 #define _GL_CONCAT0(x, y) x##y
98 #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
99 extern struct {...} * _GL_CONCAT (dummy, __LINE__);
100
101 But this has the problem that two invocations of verify from
102 within the same macro would collide, since the __LINE__ value
103 would be the same for both invocations. (The GCC __COUNTER__
104 macro solves this problem, but is not portable.)
105
106 A solution is to use the sizeof operator. It yields a number,
107 getting rid of the identity of the type. Declarations like
108
109 extern int dummy [sizeof (struct {...})];
110 extern void dummy (int [sizeof (struct {...})]);
111 extern int (*dummy (void)) [sizeof (struct {...})];
112
113 can be repeated.
114
115 * Should the implementation use a named struct or an unnamed struct?
116 Which of the following alternatives can be used?
117
118 extern int dummy [sizeof (struct {...})];
119 extern int dummy [sizeof (struct verify_type__ {...})];
120 extern void dummy (int [sizeof (struct {...})]);
121 extern void dummy (int [sizeof (struct verify_type__ {...})]);
122 extern int (*dummy (void)) [sizeof (struct {...})];
123 extern int (*dummy (void)) [sizeof (struct verify_type__ {...})];
124
125 In the second and sixth case, the struct type is exported to the
126 outer scope; two such declarations therefore collide. GCC warns
127 about the first, third, and fourth cases. So the only remaining
128 possibility is the fifth case:
129
130 extern int (*dummy (void)) [sizeof (struct {...})];
131
132 * GCC warns about duplicate declarations of the dummy function if
133 -Wredundant_decls is used. GCC 4.3 and later have a builtin
134 __COUNTER__ macro that can let us generate unique identifiers for
135 each dummy function, to suppress this warning.
136
137 * This implementation exploits the fact that older versions of GCC,
138 which do not support _Static_assert, also do not warn about the
139 last declaration mentioned above.
140
141 * In C++, any struct definition inside sizeof is invalid.
142 Use a template type to work around the problem. */
143
144 /* Concatenate two preprocessor tokens. */
145 # define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
146 # define _GL_CONCAT0(x, y) x##y
147
148 /* _GL_COUNTER is an integer, preferably one that changes each time we
149 use it. Use __COUNTER__ if it works, falling back on __LINE__
150 otherwise. __LINE__ isn't perfect, but it's better than a
151 constant. */
152 # if defined __COUNTER__ && __COUNTER__ != __COUNTER__
153 # define _GL_COUNTER __COUNTER__
154 # else
155 # define _GL_COUNTER __LINE__
156 # endif
157
158 /* Generate a symbol with the given prefix, making it unique if
159 possible. */
160 # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
161
162 /* Verify requirement R at compile-time, as an integer constant expression.
163 Return 1. */
164
165 # ifdef __cplusplus
166 template <int w>
167 struct verify_type__ { unsigned int verify_error_if_negative_size__: w; };
168 # define verify_true(R) \
169 (!!sizeof (verify_type__<(R) ? 1 : -1>))
170 # elif HAVE__STATIC_ASSERT
171 # define verify_true(R) \
172 (!!sizeof \
173 (struct { \
174 _Static_assert (R, "verify_true (" #R ")"); \
175 int verify_dummy__; \
176 }))
177 # elif HAVE_STATIC_ASSERT
178 # define verify_true(R) \
179 (!!sizeof \
180 (struct { \
181 static_assert (R, "verify_true (" #R ")"); \
182 int verify_dummy__; \
183 }))
184 # else
185 # define verify_true(R) \
186 (!!sizeof \
187 (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))
188 # endif
189
190 /* Verify requirement R at compile-time, as a declaration without a
191 trailing ';'. */
192
193 # if HAVE__STATIC_ASSERT
194 # define verify(R) _Static_assert (R, "verify (" #R ")")
195 # elif HAVE_STATIC_ASSERT
196 # define verify(R) static_assert (R, "verify (" #R ")")
197 # else
198 # define verify(R) \
199 extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)]
200 # endif
201
202 #endif