Commit b7f64c64 authored by Michael Paquier's avatar Michael Paquier

Refactor compile-time assertion checks in c.h

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.GF2287@paquier.xyz
parent a029a064
...@@ -836,43 +836,37 @@ extern void ExceptionalCondition(const char *conditionName, ...@@ -836,43 +836,37 @@ extern void ExceptionalCondition(const char *conditionName,
* The macro StaticAssertDecl() is suitable for use at file scope (outside of * The macro StaticAssertDecl() is suitable for use at file scope (outside of
* any function). * 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 * 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 * 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. * helpful error message, but it beats not getting an error at all.
*/ */
#ifndef __cplusplus #if !defined(__cplusplus) && defined(HAVE__STATIC_ASSERT)
#ifdef HAVE__STATIC_ASSERT /* Default C implementation */
#define StaticAssertStmt(condition, errmessage) \ #define StaticAssertStmt(condition, errmessage) \
do { _Static_assert(condition, errmessage); } while(0) do { _Static_assert(condition, errmessage); } while(0)
#define StaticAssertExpr(condition, errmessage) \ #define StaticAssertExpr(condition, errmessage) \
((void) ({ StaticAssertStmt(condition, errmessage); true; })) ((void) ({ StaticAssertStmt(condition, errmessage); true; }))
#define StaticAssertDecl(condition, errmessage) \ #define StaticAssertDecl(condition, errmessage) \
_Static_assert(condition, errmessage) _Static_assert(condition, errmessage)
#else /* !HAVE__STATIC_ASSERT */ #elif defined(__cplusplus) && __cpp_static_assert >= 200410
#define StaticAssertStmt(condition, errmessage) \ /* Default C++ implementation */
((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 StaticAssertStmt(condition, errmessage) \ #define StaticAssertStmt(condition, errmessage) \
static_assert(condition, errmessage) static_assert(condition, errmessage)
#define StaticAssertExpr(condition, errmessage) \ #define StaticAssertExpr(condition, errmessage) \
({ static_assert(condition, errmessage); }) ({ static_assert(condition, errmessage); })
#define StaticAssertDecl(condition, errmessage) \ #define StaticAssertDecl(condition, errmessage) \
static_assert(condition, errmessage) static_assert(condition, errmessage)
#else /* !__cpp_static_assert */ #else
/* Fallback implementation for C and C++ */
#define StaticAssertStmt(condition, errmessage) \ #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) \ #define StaticAssertExpr(condition, errmessage) \
((void) ({ StaticAssertStmt(condition, errmessage); })) StaticAssertStmt(condition, errmessage)
#define StaticAssertDecl(condition, errmessage) \ #define StaticAssertDecl(condition, errmessage) \
extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1])
#endif /* __cpp_static_assert */ #endif
#endif /* C++ */
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment