Refactor compile-time assertion checks in c.h
authorMichael Paquier
Fri, 13 Mar 2020 06:04:11 +0000 (15:04 +0900)
committerMichael Paquier
Fri, 13 Mar 2020 06:04:11 +0000 (15:04 +0900)
This commit refactors and simplifies the definitions of StaticAssertStmt,
StaticAssertExpr and StaticAssertDecl.  By unifying the C and C++
fallback implementations, this reduces the number of different
implementations from four to three.

Author: Michael Paquier
Reviewed-by: Georgios Kokolatos, Tom Lane
Discussion: https://postgr.es/m/20200204081503[email protected]

src/include/c.h

index 831c89f473dd55e3ca35f7acbc993926c851a192..6558801e5fff93523d7356868a0227c98d35e9c5 100644 (file)
@@ -836,43 +836,37 @@ extern void ExceptionalCondition(const char *conditionName,
  * The macro StaticAssertDecl() is suitable for use at file scope (outside of
  * any function).
  *
+ * On recent C++ compilers, we can use standard static_assert().
+ *
  * 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.
  */
-#ifndef __cplusplus
-#ifdef HAVE__STATIC_ASSERT
+#if !defined(__cplusplus) && defined(HAVE__STATIC_ASSERT)
+/* Default C implementation */
 #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 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
+#elif defined(__cplusplus) && __cpp_static_assert >= 200410
+/* Default C++ implementation */
 #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 */
+#else
+/* Fallback implementation for C and C++ */
 #define StaticAssertStmt(condition, errmessage) \
-   do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0)
+   ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
 #define StaticAssertExpr(condition, errmessage) \
-   ((void) ({ StaticAssertStmt(condition, errmessage); }))
+   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++ */
+#endif
 
 
 /*