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().