From 662e74060acb710edf2b56084519f1b951835cab Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 19 Feb 2026 09:42:19 +0100 Subject: [PATCH] Use standard C23 and C++ attributes if available Use the standard C23 and C++ attributes [[nodiscard]], [[noreturn]], and [[maybe_unused]], if available. This makes pg_nodiscard and pg_attribute_unused() available in not-GCC-compatible compilers that support C23 as well as in C++ (although this set is theoretical at this point). For pg_noreturn, we can now drop the GCC-specific and MSVC-specific fallbacks, because the C11 and the C++ implementation will now cover all required cases. Note, in a few places, we need to change the position of the attribute because it's not valid in that place in C23. Discussion: https://www.postgresql.org/message-id/flat/pxr5b3z7jmkpenssra5zroxi7qzzp6eswuggokw64axmdixpnk@zbwxuq7gbbcw --- src/backend/utils/mmgr/slab.c | 2 +- src/include/c.h | 38 ++++++++++++++---------- src/include/lib/radixtree.h | 2 +- src/test/modules/worker_spi/worker_spi.c | 2 +- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/mmgr/slab.c b/src/backend/utils/mmgr/slab.c index bd00bab18fe..34a9410e76a 100644 --- a/src/backend/utils/mmgr/slab.c +++ b/src/backend/utils/mmgr/slab.c @@ -628,8 +628,8 @@ SlabAllocFromNewBlock(MemoryContext context, Size size, int flags) * to setup the stack frame in SlabAlloc. For performance reasons, we * want to avoid that. */ -pg_noinline pg_noreturn +pg_noinline static void SlabAllocInvalidSize(MemoryContext context, Size size) { diff --git a/src/include/c.h b/src/include/c.h index a249674f026..8c6182a2c8e 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -111,6 +111,8 @@ /* * Attribute macros * + * C23: https://en.cppreference.com/w/c/language/attributes.html + * C++: https://en.cppreference.com/w/cpp/language/attributes.html * GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html * GCC: https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html * Clang: https://clang.llvm.org/docs/AttributeReference.html @@ -120,13 +122,20 @@ * For compilers which don't support __has_attribute, we just define * __has_attribute(x) to 0 so that we can define macros for various * __attribute__s more easily below. + * + * Note that __has_attribute only tells about GCC-style attributes, not C23 or + * C++ attributes. */ #ifndef __has_attribute #define __has_attribute(attribute) 0 #endif -/* only GCC supports the unused attribute */ -#ifdef __GNUC__ +/* + * pg_attribute_unused() suppresses compiler warnings on unused entities. + */ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || (defined(__cplusplus) && __cplusplus >= 201703L) +#define pg_attribute_unused() [[maybe_unused]] +#elif defined(__GNUC__) #define pg_attribute_unused() __attribute__((unused)) #else #define pg_attribute_unused() @@ -134,11 +143,11 @@ /* * pg_nodiscard means the compiler should warn if the result of a function - * call is ignored. The name "nodiscard" is chosen in alignment with the C23 - * standard attribute with the same name. For maximum forward compatibility, - * place it before the declaration. + * call is ignored. */ -#ifdef __GNUC__ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || (defined(__cplusplus) && __cplusplus >= 201703L) +#define pg_nodiscard [[nodiscard]] +#elif defined(__GNUC__) #define pg_nodiscard __attribute__((warn_unused_result)) #else #define pg_nodiscard @@ -150,18 +159,15 @@ * uses __attribute__((noreturn)) in headers, which would get confused if * "noreturn" is defined to "_Noreturn", as is done by . * - * In a declaration, function specifiers go before the function name. The - * common style is to put them before the return type. (The MSVC fallback has - * the same requirement. The GCC fallback is more flexible.) + * C23 attributes must be placed at the start of a declaration or statement. + * C11 function specifiers go before the function name in a declaration, but + * it is common style (and required for C23 compatibility) to put them before + * the return type. */ -#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) && !defined(__cplusplus) -#define pg_noreturn _Noreturn -#elif defined(__GNUC__) -#define pg_noreturn __attribute__((noreturn)) -#elif defined(_MSC_VER) -#define pg_noreturn __declspec(noreturn) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || defined(__cplusplus) +#define pg_noreturn [[noreturn]] #else -#define pg_noreturn +#define pg_noreturn _Noreturn #endif /* diff --git a/src/include/lib/radixtree.h b/src/include/lib/radixtree.h index b223ce10a2d..179f78137fa 100644 --- a/src/include/lib/radixtree.h +++ b/src/include/lib/radixtree.h @@ -2777,8 +2777,8 @@ RT_STATS(RT_RADIX_TREE * tree) /* * Print out debugging information about the given node. */ -static void pg_attribute_unused() +static void RT_DUMP_NODE(RT_NODE * node) { #ifdef RT_SHMEM diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c index d1e4a2bd952..f9bb16a017e 100644 --- a/src/test/modules/worker_spi/worker_spi.c +++ b/src/test/modules/worker_spi/worker_spi.c @@ -44,7 +44,7 @@ PG_MODULE_MAGIC; PG_FUNCTION_INFO_V1(worker_spi_launch); -PGDLLEXPORT pg_noreturn void worker_spi_main(Datum main_arg); +pg_noreturn PGDLLEXPORT void worker_spi_main(Datum main_arg); /* GUC variables */ static int worker_spi_naptime = 10; -- 2.53.0