From 76b8ce879e21fd79173ddf77acbb511d39b00b77 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 15 Sep 2026 08:43:09 +0200 Subject: [PATCH v2 1/8] Add unconstify_constexpr unconstify_constexpr is like unconstify but for contexts where a constant expression is required, such as for initializing global variables. It provides the same level of checking as unconstify, but the checking only works on GCC, otherwise it lets anything through. Also, if the check fails, it gives a less clear error message. So it should only be used when necessary. (An unvolatize_constexpr doesn't seem necessary, but it could be added if required.) --- src/include/c.h | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/include/c.h b/src/include/c.h index 20cfbac54e7..341076f06ad 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -1363,20 +1363,37 @@ typedef struct PGAlignedXLogBlock PGAlignedXLogBlock; * design or language restrictions prevent you from declaring that * (e.g. because a function returns both const and non-const variables). * - * Note that this only works in function scope, not for global variables (it'd - * be nice, but not trivial, to improve that). + * unconstify_constexpr is for contexts where a constant expression is + * required, such as for initializing global variables. It provides the same + * level of checking as unconstify, but the checking only works on GCC, + * otherwise it lets anything through. Also, if the check fails, it gives a + * less clear error message. So it should only be used when necessary. + * + * (An unvolatize_constexpr doesn't seem necessary, but it could be added if + * required.) */ #if defined(__cplusplus) #define unconstify(underlying_type, expr) const_cast(expr) +#define unconstify_constexpr(underlying_type, expr) const_cast(expr) #define unvolatize(underlying_type, expr) const_cast(expr) -#else +#else /* !__cplusplus */ #define unconstify(underlying_type, expr) \ (StaticAssertVariableIsOfTypeMacro(expr, const underlying_type), \ (underlying_type) (expr)) #define unvolatize(underlying_type, expr) \ (StaticAssertVariableIsOfTypeMacro(expr, volatile underlying_type), \ (underlying_type) (expr)) -#endif +#ifdef __GNUC__ +#define unconstify_constexpr(underlying_type, expr) \ + __builtin_choose_expr( \ + _Generic((expr), const underlying_type: 1, default: 0), \ + (underlying_type) (expr), \ + (void) 0) +#else /* !__GNUC_ */ +#define unconstify_constexpr(underlying_type, expr) \ + ((underlying_type) (expr)) +#endif /* !__GNUC_ */ +#endif /* !__cplusplus */ /* * SSE2 instructions are part of the spec for the 64-bit x86 ISA. We assume -- 2.55.0