summaryrefslogtreecommitdiff
path: root/src/include/c.h
diff options
context:
space:
mode:
authorMichael Paquier2020-02-03 05:48:42 +0000
committerMichael Paquier2020-02-03 05:48:42 +0000
commitf1f10a1ba9e17e606a7b217ccccdd3cc4d8cb771 (patch)
tree2ad0e6861232bcef32bc0924469de3958b86cdb4 /src/include/c.h
parent6148e2b9a6399b77e10e277c32d701b84703820f (diff)
Add declaration-level assertions for compile-time checks
Those new assertions can be used at file scope, outside of any function for compilation checks. This commit provides implementations for C and C++, and fallback implementations. Author: Peter Smith Reviewed-by: Andres Freund, Kyotaro Horiguchi, Dagfinn Ilmari Mannsåker, Michael Paquier Discussion: https://postgr.es/m/201DD0641B056142AC8C6645EC1B5F62014B8E8030@SYD1217
Diffstat (limited to 'src/include/c.h')
-rw-r--r--src/include/c.h18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/include/c.h b/src/include/c.h
index 6898229b43e..d10b9812fbe 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -832,8 +832,10 @@ extern void ExceptionalCondition(const char *conditionName,
* 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. These macros make it safe to use as a statement
- * or in an expression, respectively.
+ * placement restrictions. 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
@@ -845,11 +847,15 @@ extern void ExceptionalCondition(const char *conditionName,
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 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
@@ -857,12 +863,16 @@ extern void ExceptionalCondition(const char *conditionName,
static_assert(condition, errmessage)
#define StaticAssertExpr(condition, errmessage) \
({ static_assert(condition, errmessage); })
-#else
+#define StaticAssertDecl(condition, errmessage) \
+ static_assert(condition, errmessage)
+#else /* !__cpp_static_assert */
#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); }))
-#endif
+#define StaticAssertDecl(condition, errmessage) \
+ extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1])
+#endif /* __cpp_static_assert */
#endif /* C++ */