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 bcd3f5a0..4ad780c8 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 |
