annotate lib/verify.h @ 14529:be9a4084509a

verify: use _Static_assert if available * lib/verify.h (HAVE__STATIC_ASSERT): New macro. (verify_true, verify): Use it if available. This generates better diagnostics with GCC 4.6.0 and later.
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 05 Apr 2011 23:45:10 -0700
parents 97fc9a21a8fb
children bfd6bd3592ec
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6267
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
1 /* Compile-time assert-like macros.
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
2
14079
97fc9a21a8fb maint: update almost all copyright ranges to include 2011
Jim Meyering <meyering@redhat.com>
parents: 13325
diff changeset
3 Copyright (C) 2005-2006, 2009-2011 Free Software Foundation, Inc.
6267
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
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
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
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
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
9
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
13 GNU General Public License for more details.
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
14
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
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
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
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
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
19
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
20 #ifndef VERIFY_H
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
21 # define VERIFY_H 1
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
22
14529
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
23 /* Define HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
24 C1X draft N1548 section 6.7.10. This is supported by GCC 4.6.0 and
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
25 later, and its use here generates easier-to-read diagnostics when
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
26 verify (R) fails.
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
27
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
28 For now, use this only with GCC. Eventually whether _Static_assert
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
29 works should be determined by 'configure'. */
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
30 # if 4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
31 # define HAVE__STATIC_ASSERT 1
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
32 # endif
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
33
6766
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
34 /* 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
35 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
36 assert (R), there is no run-time overhead.
6267
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
37
6302
71bde2024cdc (verify_expr): Remove, replacing with:
Paul Eggert <eggert@cs.ucla.edu>
parents: 6290
diff changeset
38 There are two macros, since no single macro can be used in all
6766
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
39 contexts in C. verify_true (R) is for scalar contexts, including
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
40 integer constant expression contexts. verify (R) is for declaration
6302
71bde2024cdc (verify_expr): Remove, replacing with:
Paul Eggert <eggert@cs.ucla.edu>
parents: 6290
diff changeset
41 contexts, e.g., the top level.
6267
58c87cabeb1c * modules/verify: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
42
6766
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
43 Symbols ending in "__" are private to this header.
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
44
14529
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
45 If _Static_assert works, verify (R) uses it directly. Similarly,
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
46 verify_true (R) works by packaging a _Static_assert inside a struct
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
47 that is an operand of sizeof.
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
48
be9a4084509a verify: use _Static_assert if available
Paul Eggert <eggert@cs.ucla.edu>
parents: 14079
diff changeset
49 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
50 compilers that do not support _Static_assert:
6766
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
51
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
52 * 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
53 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
54 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
55 constant and nonnegative.
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
56
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
57 * Next this expression W is wrapped in a type
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
58 struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }.
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
59 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
60 deal with a bit-field of negative size.
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
61
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
62 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
63 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
64 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
65 (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
66 variables inside array size expressions. With these compilers,
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
67 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
68 the verify macro:
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
69
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
70 void function (int n) { verify (n < 0); }
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
71
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
72 * For the verify macro, the struct verify_type__ will need to
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6329
diff changeset
73 somehow be embedded into a declaration. To be portable, this
a1a506584827 * doc/verify.texi: New file.
Paul Eggert <eggert@cs.ucla.edu>