diff options
Diffstat (limited to 'gl/verify.h')
-rw-r--r-- | gl/verify.h | 41 |
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 |