]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
lib/sizeof.h: typeas(): Add macro
authorAlejandro Colomar <alx@kernel.org>
Sat, 15 Nov 2025 19:21:25 +0000 (20:21 +0100)
committerSerge Hallyn <serge@hallyn.com>
Fri, 5 Dec 2025 14:34:32 +0000 (08:34 -0600)
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 <alx@kernel.org>
Suggested-by: Thiago Adams <thiago.adams@gmail.com>
Suggested-by: Martin Uecker <uecker@tugraz.at>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/sizeof.h

index 5b63efd5f90d82ea9107e7dd487f324c9ec84e03..469bfde5ff20d057f87ac50d62a18106b5329ce3 100644 (file)
@@ -15,6 +15,8 @@
 #include <sys/types.h>
 
 
+#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)