Mercurial > hg > octave-shane > gnulib-hg
annotate lib/verify.h @ 17255:d81be792518a
update from texinfo
author | Karl Berry <karl@freefriends.org> |
---|---|
date | Tue, 01 Jan 2013 15:51:49 -0800 |
parents | e542fd46ad6f |
children | 6105f1dfb98e |
rev | line source |
---|---|
6267 | 1 /* Compile-time assert-like macros. |
2 | |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
17002
diff
changeset
|
3 Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc. |
6267 | 4 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
6766
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
6267 | 6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
6766
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
6766
diff
changeset
|
8 (at your option) any later version. |
6267 | 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 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
6766
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
6267 | 17 |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
18 /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ |
6267 | 19 |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
20 #ifndef _GL_VERIFY_H |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
21 # define _GL_VERIFY_H |
6267 | 22 |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
23 |
16239
91f53c1e1787
doc: C11 and C++11 are now official
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
24 /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. |
91f53c1e1787
doc: C11 and C++11 are now official
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
25 This is supported by GCC 4.6.0 and later, in C mode, and its use |
91f53c1e1787
doc: C11 and C++11 are now official
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
26 here generates easier-to-read diagnostics when verify (R) fails. |
14551
bfd6bd3592ec
verify: Fix syntax error with GCC 4.6 in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
14529
diff
changeset
|
27 |
16239
91f53c1e1787
doc: C11 and C++11 are now official
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
28 Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11. |
14551
bfd6bd3592ec
verify: Fix syntax error with GCC 4.6 in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
14529
diff
changeset
|
29 This will likely be supported by future GCC versions, in C++ mode. |
14529
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
30 |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
31 Use this only with GCC. If we were willing to slow 'configure' |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
32 down we could also use it with other compilers, but since this |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
33 affects only the quality of diagnostics, why bother? */ |
14551
bfd6bd3592ec
verify: Fix syntax error with GCC 4.6 in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
14529
diff
changeset
|
34 # if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
35 # define _GL_HAVE__STATIC_ASSERT 1 |
14529
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
36 # endif |
14551
bfd6bd3592ec
verify: Fix syntax error with GCC 4.6 in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
14529
diff
changeset
|
37 /* The condition (99 < __GNUC__) is temporary, until we know about the |
bfd6bd3592ec
verify: Fix syntax error with GCC 4.6 in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
14529
diff
changeset
|
38 first G++ release that supports static_assert. */ |
bfd6bd3592ec
verify: Fix syntax error with GCC 4.6 in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
14529
diff
changeset
|
39 # if (99 < __GNUC__) && defined __cplusplus |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
40 # define _GL_HAVE_STATIC_ASSERT 1 |
14551
bfd6bd3592ec
verify: Fix syntax error with GCC 4.6 in C++ mode.
Bruno Haible <bruno@clisp.org>
parents:
14529
diff
changeset
|
41 # endif |
14529
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
42 |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
43 /* Each of these macros verifies that its argument R is nonzero. To |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
44 be portable, R should be an integer constant expression. Unlike |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
45 assert (R), there is no run-time overhead. |
6267 | 46 |
14529
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
47 If _Static_assert works, verify (R) uses it directly. Similarly, |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
48 _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct |
14529
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
49 that is an operand of sizeof. |
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
50 |
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
51 The code below uses several ideas for C++ compilers, and for C |
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
52 compilers that do not support _Static_assert: |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
53 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
54 * The first step is ((R) ? 1 : -1). Given an expression R, of |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
55 integral or boolean or floating-point type, this yields an |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
56 expression of integral type, whose value is later verified to be |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
57 constant and nonnegative. |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
58 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
59 * Next this expression W is wrapped in a type |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
60 struct _gl_verify_type { |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
61 unsigned int _gl_verify_error_if_negative: W; |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
62 }. |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
63 If W is negative, this yields a compile-time error. No compiler can |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
64 deal with a bit-field of negative size. |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
65 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
66 One might think that an array size check would have the same |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
67 effect, that is, that the type struct { unsigned int dummy[W]; } |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
68 would work as well. However, inside a function, some compilers |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
69 (such as C++ compilers and GNU C) allow local parameters and |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
70 variables inside array size expressions. With these compilers, |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
71 an array size check would not properly diagnose this misuse of |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
72 the verify macro: |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
73 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
74 void function (int n) { verify (n < 0); } |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
75 |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
76 * For the verify macro, the struct _gl_verify_type will need to |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
77 somehow be embedded into a declaration. To be portable, this |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
78 declaration must declare an object, a constant, a function, or a |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
79 typedef name. If the declared entity uses the type directly, |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
80 such as in |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
81 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
82 struct dummy {...}; |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
83 typedef struct {...} dummy; |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
84 extern struct {...} *dummy; |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
85 extern void dummy (struct {...} *); |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
86 extern struct {...} *dummy (void); |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
87 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
88 two uses of the verify macro would yield colliding declarations |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
89 if the entity names are not disambiguated. A workaround is to |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
90 attach the current line number to the entity name: |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
91 |
13318
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
92 #define _GL_CONCAT0(x, y) x##y |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
93 #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) |
13325
3ec28439ec92
verify: adjust formatting to be more consistent
Jim Meyering <meyering@redhat.com>
parents:
13318
diff
changeset
|
94 extern struct {...} * _GL_CONCAT (dummy, __LINE__); |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
95 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
96 But this has the problem that two invocations of verify from |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
97 within the same macro would collide, since the __LINE__ value |
13317
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
98 would be the same for both invocations. (The GCC __COUNTER__ |
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
99 macro solves this problem, but is not portable.) |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
100 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
101 A solution is to use the sizeof operator. It yields a number, |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
102 getting rid of the identity of the type. Declarations like |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
103 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
104 extern int dummy [sizeof (struct {...})]; |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
105 extern void dummy (int [sizeof (struct {...})]); |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
106 extern int (*dummy (void)) [sizeof (struct {...})]; |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
107 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
108 can be repeated. |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
109 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
110 * Should the implementation use a named struct or an unnamed struct? |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
111 Which of the following alternatives can be used? |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
112 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
113 extern int dummy [sizeof (struct {...})]; |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
114 extern int dummy [sizeof (struct _gl_verify_type {...})]; |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
115 extern void dummy (int [sizeof (struct {...})]); |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
116 extern void dummy (int [sizeof (struct _gl_verify_type {...})]); |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
117 extern int (*dummy (void)) [sizeof (struct {...})]; |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
118 extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})]; |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
119 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
120 In the second and sixth case, the struct type is exported to the |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
121 outer scope; two such declarations therefore collide. GCC warns |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
122 about the first, third, and fourth cases. So the only remaining |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
123 possibility is the fifth case: |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
124 |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
125 extern int (*dummy (void)) [sizeof (struct {...})]; |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
126 |
13317
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
127 * GCC warns about duplicate declarations of the dummy function if |
17002
0103491fe167
verify: document conflict with -Wnested-externs
Eric Blake <eblake@redhat.com>
parents:
16239
diff
changeset
|
128 -Wredundant-decls is used. GCC 4.3 and later have a builtin |
13317
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
129 __COUNTER__ macro that can let us generate unique identifiers for |
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
130 each dummy function, to suppress this warning. |
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
131 |
14529
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
132 * This implementation exploits the fact that older versions of GCC, |
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
133 which do not support _Static_assert, also do not warn about the |
be9a4084509a
verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
134 last declaration mentioned above. |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
135 |
17002
0103491fe167
verify: document conflict with -Wnested-externs
Eric Blake <eblake@redhat.com>
parents:
16239
diff
changeset
|
136 * GCC warns if -Wnested-externs is enabled and verify() is used |
0103491fe167
verify: document conflict with -Wnested-externs
Eric Blake <eblake@redhat.com>
parents:
16239
diff
changeset
|
137 within a function body; but inside a function, you can always |
0103491fe167
verify: document conflict with -Wnested-externs
Eric Blake <eblake@redhat.com>
parents:
16239
diff
changeset
|
138 arrange to use verify_expr() instead. |
0103491fe167
verify: document conflict with -Wnested-externs
Eric Blake <eblake@redhat.com>
parents:
16239
diff
changeset
|
139 |
6766
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
140 * In C++, any struct definition inside sizeof is invalid. |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
141 Use a template type to work around the problem. */ |
a1a506584827
* doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6329
diff
changeset
|
142 |
13317
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
143 /* Concatenate two preprocessor tokens. */ |
13318
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
144 # define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
145 # define _GL_CONCAT0(x, y) x##y |
13317
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
146 |
13318
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
147 /* _GL_COUNTER is an integer, preferably one that changes each time we |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
148 use it. Use __COUNTER__ if it works, falling back on __LINE__ |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
149 otherwise. __LINE__ isn't perfect, but it's better than a |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
150 constant. */ |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
151 # if defined __COUNTER__ && __COUNTER__ != __COUNTER__ |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
152 # define _GL_COUNTER __COUNTER__ |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
153 # else |
a69ddb2f39de
Further improvements to verify.h, suggested by Eric Blake.
Paul Eggert <eggert@cs.ucla.edu>
parents:
13317
diff
changeset
|
154 # define _GL_COUNTER __LINE__ |
13317
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
155 # endif |
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
156 |
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
157 /* Generate a symbol with the given prefix, making it unique if |
f4cec457476e
Modify verify.h to pacify gcc -Wredundant_decls.
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
158 possible. */ |
13325
3ec28439ec92
verify: adjust formatting to be more consistent
Jim Meyering <meyering@redhat.com>
parents:
13318
diff
changeset
|
159 # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) |
6267 | 160 |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
161 /* Verify requirement R at compile-time, as an integer constant expression |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
162 that returns 1. If R is false, fail at compile-time, preferably |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
163 with a diagnostic that includes the string-literal DIAGNOSTIC. */ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
164 |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
165 # define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
166 (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) |
6267 | 167 |
6329
ffad934ef3bd
* verify.h (verify_true): Provide alternative definition for C++.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6302
diff
changeset
|
168 # ifdef __cplusplus |
14839
984611ea5a25
assert-h: Allow multiple gnulib generated replacements to coexist.
Bruno Haible <bruno@clisp.org>
parents:
14799
diff
changeset
|
169 # if !GNULIB_defined_struct__gl_verify_type |
6329
ffad934ef3bd
* verify.h (verify_true): Provide alternative definition for C++.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6302
diff
changeset
|
170 template <int w> |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
171 struct _gl_verify_type { |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
172 unsigned int _gl_verify_error_if_negative: w; |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
173 }; |
14839
984611ea5a25
assert-h: Allow multiple gnulib generated replacements to coexist.
Bruno Haible <bruno@clisp.org>
parents:
14799
diff
changeset
|
174 # define GNULIB_defined_struct__gl_verify_type 1 |
984611ea5a25
assert-h: Allow multiple gnulib generated replacements to coexist.
Bruno Haible <bruno@clisp.org>
parents:
14799
diff
changeset
|
175 # endif |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
176 # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
177 _gl_verify_type<(R) ? 1 : -1> |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
178 # elif defined _GL_HAVE__STATIC_ASSERT |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
179 # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
180 struct { \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
181 _Static_assert (R, DIAGNOSTIC); \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
182 int _gl_dummy; \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
183 } |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
184 # else |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
185 # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
186 struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
187 # endif |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
188 |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
189 /* Verify requirement R at compile-time, as a declaration without a |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
190 trailing ';'. If R is false, fail at compile-time, preferably |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
191 with a diagnostic that includes the string-literal DIAGNOSTIC. |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
192 |
16239
91f53c1e1787
doc: C11 and C++11 are now official
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
193 Unfortunately, unlike C11, this implementation must appear as an |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
194 ordinary declaration, and cannot appear inside struct { ... }. */ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
195 |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
196 # ifdef _GL_HAVE__STATIC_ASSERT |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
197 # define _GL_VERIFY _Static_assert |
6329
ffad934ef3bd
* verify.h (verify_true): Provide alternative definition for C++.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6302
diff
changeset
|
198 # else |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
199 # define _GL_VERIFY(R, DIAGNOSTIC) \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
200 extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
201 [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] |
6329
ffad934ef3bd
* verify.h (verify_true): Provide alternative definition for C++.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6302
diff
changeset
|
202 # endif |
6267 | 203 |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
204 /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
205 # ifdef _GL_STATIC_ASSERT_H |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
206 # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
207 # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
208 # endif |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
209 # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert |
16239
91f53c1e1787
doc: C11 and C++11 are now official
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
210 # define static_assert _Static_assert /* C11 requires this #define. */ |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
211 # endif |
14799
8c6279c6c551
verify: fix bug when gnulib <assert.h> is also included
Paul Eggert <eggert@cs.ucla.edu>
parents:
14698
diff
changeset
|
212 # endif |
8c6279c6c551
verify: fix bug when gnulib <assert.h> is also included
Paul Eggert <eggert@cs.ucla.edu>
parents:
14698
diff
changeset
|
213 |
14846
a8d8fc44bcc4
assert-h: work around 'verify' incompatibility
Paul Eggert <eggert@cs.ucla.edu>
parents:
14839
diff
changeset
|
214 /* @assert.h omit start@ */ |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
215 |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
216 /* Each of these macros verifies that its argument R is nonzero. To |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
217 be portable, R should be an integer constant expression. Unlike |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
218 assert (R), there is no run-time overhead. |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
219 |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
220 There are two macros, since no single macro can be used in all |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
221 contexts in C. verify_true (R) is for scalar contexts, including |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
222 integer constant expression contexts. verify (R) is for declaration |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
223 contexts, e.g., the top level. */ |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
224 |
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
225 /* Verify requirement R at compile-time, as an integer constant expression. |
14922
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
226 Return 1. This is equivalent to verify_expr (R, 1). |
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
227 |
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
228 verify_true is obsolescent; please use verify_expr instead. */ |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
229 |
14846
a8d8fc44bcc4
assert-h: work around 'verify' incompatibility
Paul Eggert <eggert@cs.ucla.edu>
parents:
14839
diff
changeset
|
230 # define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
231 |
14922
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
232 /* Verify requirement R at compile-time. Return the value of the |
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
233 expression E. */ |
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
234 |
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
235 # define verify_expr(R, E) \ |
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
236 (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) |
75807d4b7597
verify: new macro verify_expr; verify_true deprecated
Paul Eggert <eggert@cs.ucla.edu>
parents:
14846
diff
changeset
|
237 |
6302
71bde2024cdc
(verify_expr): Remove, replacing with:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6290
diff
changeset
|
238 /* Verify requirement R at compile-time, as a declaration without a |
71bde2024cdc
(verify_expr): Remove, replacing with:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6290
diff
changeset
|
239 trailing ';'. */ |
71bde2024cdc
(verify_expr): Remove, replacing with:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6290
diff
changeset
|
240 |
14846
a8d8fc44bcc4
assert-h: work around 'verify' incompatibility
Paul Eggert <eggert@cs.ucla.edu>
parents:
14839
diff
changeset
|
241 # define verify(R) _GL_VERIFY (R, "verify (" #R ")") |
14698
cb78c05783f7
assert-h: new module, which supports C1X-style static_assert
Paul Eggert <eggert@cs.ucla.edu>
parents:
14551
diff
changeset
|
242 |
14846
a8d8fc44bcc4
assert-h: work around 'verify' incompatibility
Paul Eggert <eggert@cs.ucla.edu>
parents:
14839
diff
changeset
|
243 /* @assert.h omit end@ */ |
6267 | 244 |
245 #endif |