From 8c1ed7af27a51614a582f6ddccbd2b5d84f3542a Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Wed, 29 Jul 2026 23:31:25 +0200 Subject: [PATCH] lib/sizeof.h: typeas(): Add support for 'void' and function types typeas() should be a generic macro that accepts any types that typeof() accepts. The current implementation, while simple, didn't allow 'void' and function types, since one can't create a compound literal of such a type. The solution needs to create a pointer type, which accepts a compound literal even for void and function pointee types. This requires using typeof() within the parenthesized type of the compound literal, and thus we need a different way to validate that the input is a type name (not an expression), which is done through _Generic(). Here's an expanded version of it, to help review it: #define typeas(T) typeof \ ( \ *(typeof(T) *){ \ _Generic(0, T: NULL, default: NULL) \ } \ ) For the source code, let's keep it as a one-liner. BTW, a nice side effect of this implementation is that we use {NULL} instead of {0}, and thus we get rid of -Wzero-as-null-pointer-constant diagnostics when the type T is a pointer type. This implementation remains compatible to GNU C11 --and ISO C23, which standardized typeof()--. Cc: Martin Uecker Signed-off-by: Alejandro Colomar --- lib/sizeof.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/sizeof.h b/lib/sizeof.h index 1fc38873dd..99f839cf92 100644 --- a/lib/sizeof.h +++ b/lib/sizeof.h @@ -12,10 +12,11 @@ #if __has_include() # include #endif +#include #include -#define typeas(T) typeof((T){0}) +#define typeas(T) typeof(*(typeof(T) *){_Generic(0, T: NULL, default: NULL)}) #define ssizeof(x) ({(ssize_t){sizeof(x)};}) #define memberof(T, member) ((T){}.member)