summaryrefslogtreecommitdiff
path: root/src/include/c.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/c.h')
-rw-r--r--src/include/c.h33
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++ */