On Thu, Mar 12, 2020 at 12:33:21AM -0400, Tom Lane wrote: > I looked at this and tried it on an old (non HAVE__STATIC_ASSERT) > gcc version. Seems to work, but I have a couple cosmetic suggestions:
Thanks for the review. > 1. The comment block above this was never updated to mention that > we're now catering for C++ too. Maybe something like > > + * On recent C++ compilers, we can use standard static_assert(). > + * Sounds fine to me. Looking here this is present since GCC 4.3: https://gcc.gnu.org/projects/cxx-status.html#cxx11 For MSVC, actually I was a bit wrong, only the flavor without error message is supported since VS 2017, and the one we use is much older: https://docs.microsoft.com/en-us/cpp/cpp/static-assert?view=vs-2015 So, should we add a reference about both in the new comment? I would actually not add them, so I have used your suggestion in the attached, but the comment block above does that for _Static_assert(). Do you think it is better to add some references to some of those compilers (say GCC 4.3, MSVC)? Just stick with your suggestion? Or stick with your version and replace the reference to GCC 4.6 with something like "recent compilers"? > 2. I think you could simplify the #elif to just > > #elif defined(__cplusplus) && __cpp_static_assert >= 200410 > > Per the C standard, an unrecognized identifier in an #if condition > is replaced by zero. So the condition will come out false as desired > if __cpp_static_assert isn't defined; you don't need to test that > separately. Thanks, indeed. -- Michael
From 43a5636b64a0d337bfc88177cd138f67ed291bba Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@paquier.xyz> Date: Thu, 12 Mar 2020 16:10:34 +0900 Subject: [PATCH v3] Refactor assertion definitions in c.h This unifies the C and C++ fallback implementations. --- src/include/c.h | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/include/c.h b/src/include/c.h index 831c89f473..6558801e5f 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -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 /* -- 2.25.1
signature.asc
Description: PGP signature