diff options
Diffstat (limited to 'src/include/c.h')
| -rw-r--r-- | src/include/c.h | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/src/include/c.h b/src/include/c.h index 98cdd285dd9..bd6d8e5bf53 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -847,47 +847,50 @@ extern void ExceptionalCondition(const char *conditionName, * If the "condition" (a compile-time-constant expression) evaluates to false, * throw a compile error using the "errmessage" (a string literal). * - * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic - * placement restrictions. Macros StaticAssertStmt() and StaticAssertExpr() + * C11 has _Static_assert(), and most C99 compilers already support that. For + * portability, we wrap it into StaticAssertDecl(). _Static_assert() is a + * "declaration", and so it must be placed where for example a variable + * declaration would be valid. As long as we compile with + * -Wno-declaration-after-statement, that also means it cannot be placed after + * statements in a function. Macros StaticAssertStmt() and StaticAssertExpr() * make it safe to use as a statement or in an expression, respectively. - * The macro StaticAssertDecl() is suitable for use at file scope (outside of - * any function). * - * Otherwise we fall back on a kluge that assumes the compiler will complain - * about a negative width for a struct bit-field. This will not include a - * helpful error message, but it beats not getting an error at all. + * For compilers without _Static_assert(), we fall back on a kluge that + * assumes the compiler will complain about a negative width for a struct + * bit-field. This will not include a helpful error message, but it beats not + * getting an error at all. */ #ifndef __cplusplus #ifdef HAVE__STATIC_ASSERT +#define StaticAssertDecl(condition, errmessage) \ + _Static_assert(condition, errmessage) #define StaticAssertStmt(condition, errmessage) \ do { _Static_assert(condition, errmessage); } while(0) #define StaticAssertExpr(condition, errmessage) \ ((void) ({ StaticAssertStmt(condition, errmessage); true; })) -#define StaticAssertDecl(condition, errmessage) \ - _Static_assert(condition, errmessage) #else /* !HAVE__STATIC_ASSERT */ +#define StaticAssertDecl(condition, errmessage) \ + extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) #define StaticAssertStmt(condition, errmessage) \ ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) #define StaticAssertExpr(condition, errmessage) \ StaticAssertStmt(condition, errmessage) -#define StaticAssertDecl(condition, errmessage) \ - extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) #endif /* HAVE__STATIC_ASSERT */ #else /* C++ */ #if defined(__cpp_static_assert) && __cpp_static_assert >= 200410 +#define StaticAssertDecl(condition, errmessage) \ + static_assert(condition, errmessage) #define StaticAssertStmt(condition, errmessage) \ static_assert(condition, errmessage) #define StaticAssertExpr(condition, errmessage) \ ({ static_assert(condition, errmessage); }) -#define StaticAssertDecl(condition, errmessage) \ - static_assert(condition, errmessage) #else /* !__cpp_static_assert */ +#define StaticAssertDecl(condition, errmessage) \ + extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) #define StaticAssertStmt(condition, errmessage) \ do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0) #define StaticAssertExpr(condition, errmessage) \ ((void) ({ StaticAssertStmt(condition, errmessage); })) -#define StaticAssertDecl(condition, errmessage) \ - extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) #endif /* __cpp_static_assert */ #endif /* C++ */ |
