]> git.ipfire.org Git - thirdparty/shadow.git/commit
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)
commit97d3c09a3d357bf4ade04b24afeb8d2e5ec6bf73
tree7c94b7214af23ec19e25a78a015b20d5c191a100
parent9eec34396489abe675bdd26a4b278f808baba97d
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 <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