On Fri, 18 Jul 2025 at 14:34, H. Peter Anvin hpa@zytor.com wrote:
__auto_type __pu_ptr = (ptr); \
auto __pu_ptr = (ptr); \ typeof(*__pu_ptr) __pu_val = (typeof(*__pu_ptr))(x); \
Side note: I think some coccinelle (or sed) script that replaces that older form of
typeof(x) Y = (typeof(x))(Z);
or
typeof(Z) Y = Z;
with just
auto Y = Z;
is also worthwhile at some point.
We have more of those, because that's the really traditional gcc way to do things that predates __auto_type.
And the patterns are a bit more complicated, so they need care: not all of the "typeof (x) Z = Y" patterns have the same type in the assignment.
So it's not the universal case, but it's the _common_ case, I think.
For example, it's obviously the case in the above, where we use the exact same "typeof" on both sides, but in other uaccess.h files we also have patterns like
__typeof__(*(ptr)) __x = (x); /* eval x once */ __typeof__(ptr) __ptr = (ptr); /* eval ptr once */
where that *first* case very much needs to use that "__typeof__" model, because 'x' typically does not necessarily have the same type as '*(ptr)' (and we absolutely do not want to use a cast: we want integer types to convert naturally, but we very much want warnings if somebody were to mix types wrong).
But that second case obviously is exactly the "auto type" case, just written using __typeof__.
Linus