From 97d3c09a3d357bf4ade04b24afeb8d2e5ec6bf73 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sat, 15 Nov 2025 20:21:25 +0100 Subject: [PATCH] lib/sizeof.h: typeas(): Add macro This macro is like typeof(), but requires that the input is a type name. This macro is useful because it parenthesizes the type name, which allows one to create pointers to arbitrary types. The following code works for simple types: T x; T *p; For example, that would work fine for 'int': int x; int *p; However, that wouldn't work for types such as 'int[3]': int[3] x; int[3] *p; But if we do instead typeas(T) x; typeas(T) *p; now we can use 'int[3]' just fine: typeof((int[3]){}) x; typeof((int[3]){}) *p; To understand this, we create a compound literal of type int[3], with default values (zero, zero, zero), then get it's type, which is obviously int[3]. And then we use that to declare a variable x of that type, and a pointer p, which has type 'int(*)[3]'. This would also work with something simpler. One could use typeof(T) directly: typeof(T) x; typeof(T) *p; However, typeof() doesn't require that the input is a type; it accepts arbitrary input. The following is valid C: typeof(42) x; For our macro MALLOC(), where we want the second argument to be a type name, we want to require that the argument is a type name. For that, we need to use typeas(). Reported-by: Alejandro Colomar Suggested-by: Thiago Adams Suggested-by: Martin Uecker Signed-off-by: Alejandro Colomar --- lib/sizeof.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/sizeof.h b/lib/sizeof.h index 5b63efd5f..469bfde5f 100644 --- a/lib/sizeof.h +++ b/lib/sizeof.h @@ -15,6 +15,8 @@ #include +#define typeas(T) typeof((T){}) + #define ssizeof(x) ((ssize_t) sizeof(x)) #define memberof(T, member) ((T){}.member) #define WIDTHOF(x) (sizeof(x) * CHAR_BIT) -- 2.47.3