On Sun, 28 Jul 2024 at 07:18, David Laight <David.Laight@xxxxxxxxxx> wrote: > > +#define min_t(type, x, y) __careful_cmp(min, (type)(x), (type)(y)) > +#define max_t(type, x, y) __careful_cmp(max, (type)(x), (type)(y)) This is unrelated to your patch, but since it moves things around and touches these, I reacted to it.. We should *not* use __careful_cmp() here. Why? Because part of __careful_cmp() is the "only use arguments once". But *another* part of __careful_cmp() is "be careful about the types" in __cmp_once(). And being careful about the types is what causes horrendous expansion, and is pointless when we just forced things to be the same type. So we should split __careful_cmp() into one that does just the "do once" and one that then also does the type checking. But I think even if we don't do that, I wonder if we can just do this: #define __cmp_once(op, x, y, unique_x, unique_y) ({ \ typeof(x) unique_x = (x); \ typeof(y) unique_y = (y); \ static_assert(__types_ok(x, y), \ ... and change it to #define __cmp_once(op, x, y, unique_x, unique_y) ({ \ __auto_type unique_x = (x); \ __auto_type unique_y = (y); \ static_assert(__types_ok(unique_x, unique_y), \ ... because while that may screw up the "constant integer" case (because it now goes through that "unique_XY" variable, maybe it doesn't? At least gcc has been known to deal with things like arguments to inline functions well enough (ie a constant argument means that the arguments shows as __builtin_constant_p(), and we already depend on that). That single change would cut down on duplication of 'x' and 'y' _enormously_. No? (You already did the __auto_type part elsewhere) Note that this would require the more relaxed "__is_noneg_int()" that I suggested that allows for any expression, not just C constant expressions) Linus