summaryrefslogtreecommitdiffstats
path: root/gl/verify.h
diff options
context:
space:
mode:
Diffstat (limited to 'gl/verify.h')
-rw-r--r--gl/verify.h41
1 files changed, 32 insertions, 9 deletions
diff --git a/gl/verify.h b/gl/verify.h
index bcd3f5a..4ad780c 100644
--- a/gl/verify.h
+++ b/gl/verify.h
@@ -69,13 +69,14 @@
69 if the entity names are not disambiguated. A workaround is to 69 if the entity names are not disambiguated. A workaround is to
70 attach the current line number to the entity name: 70 attach the current line number to the entity name:
71 71
72 #define GL_CONCAT0(x, y) x##y 72 #define _GL_CONCAT0(x, y) x##y
73 #define GL_CONCAT(x, y) GL_CONCAT0 (x, y) 73 #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
74 extern struct {...} * GL_CONCAT(dummy,__LINE__); 74 extern struct {...} * _GL_CONCAT (dummy, __LINE__);
75 75
76 But this has the problem that two invocations of verify from 76 But this has the problem that two invocations of verify from
77 within the same macro would collide, since the __LINE__ value 77 within the same macro would collide, since the __LINE__ value
78 would be the same for both invocations. 78 would be the same for both invocations. (The GCC __COUNTER__
79 macro solves this problem, but is not portable.)
79 80
80 A solution is to use the sizeof operator. It yields a number, 81 A solution is to use the sizeof operator. It yields a number,
81 getting rid of the identity of the type. Declarations like 82 getting rid of the identity of the type. Declarations like
@@ -103,20 +104,41 @@
103 104
104 extern int (*dummy (void)) [sizeof (struct {...})]; 105 extern int (*dummy (void)) [sizeof (struct {...})];
105 106
107 * GCC warns about duplicate declarations of the dummy function if
108 -Wredundant_decls is used. GCC 4.3 and later have a builtin
109 __COUNTER__ macro that can let us generate unique identifiers for
110 each dummy function, to suppress this warning.
111
106 * This implementation exploits the fact that GCC does not warn about 112 * This implementation exploits the fact that GCC does not warn about
107 the last declaration mentioned above. If a future version of GCC 113 the last declaration mentioned above. If a future version of GCC
108 introduces a warning for this, the problem could be worked around 114 introduces a warning for this, the problem could be worked around
109 by using code specialized to GCC, e.g.,: 115 by using code specialized to GCC, just as __COUNTER__ is already
116 being used if available.
110 117
111 #if 4 <= __GNUC__ 118 #if 4 <= __GNUC__
112 # define verify(R) \ 119 # define verify(R) [another version to keep GCC happy]
113 extern int (* verify_function__ (void)) \
114 [__builtin_constant_p (R) && (R) ? 1 : -1]
115 #endif 120 #endif
116 121
117 * In C++, any struct definition inside sizeof is invalid. 122 * In C++, any struct definition inside sizeof is invalid.
118 Use a template type to work around the problem. */ 123 Use a template type to work around the problem. */
119 124
125/* Concatenate two preprocessor tokens. */
126# define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
127# define _GL_CONCAT0(x, y) x##y
128
129/* _GL_COUNTER is an integer, preferably one that changes each time we
130 use it. Use __COUNTER__ if it works, falling back on __LINE__
131 otherwise. __LINE__ isn't perfect, but it's better than a
132 constant. */
133# if defined __COUNTER__ && __COUNTER__ != __COUNTER__
134# define _GL_COUNTER __COUNTER__
135# else
136# define _GL_COUNTER __LINE__
137# endif
138
139/* Generate a symbol with the given prefix, making it unique if
140 possible. */
141# define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
120 142
121/* Verify requirement R at compile-time, as an integer constant expression. 143/* Verify requirement R at compile-time, as an integer constant expression.
122 Return 1. */ 144 Return 1. */
@@ -135,6 +157,7 @@ template <int w>
135/* Verify requirement R at compile-time, as a declaration without a 157/* Verify requirement R at compile-time, as a declaration without a
136 trailing ';'. */ 158 trailing ';'. */
137 159
138# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)] 160# define verify(R) \
161 extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)]
139 162
140#endif 163#endif