|
10 | 10 | /*
|
11 | 11 | * min()/max()/clamp() macros must accomplish three things:
|
12 | 12 | *
|
13 |
| - * - avoid multiple evaluations of the arguments (so side-effects like |
| 13 | + * - Avoid multiple evaluations of the arguments (so side-effects like |
14 | 14 | * "x++" happen only once) when non-constant.
|
15 |
| - * - perform signed v unsigned type-checking (to generate compile |
16 |
| - * errors instead of nasty runtime surprises). |
17 |
| - * - retain result as a constant expressions when called with only |
| 15 | + * - Retain result as a constant expressions when called with only |
18 | 16 | * constant expressions (to avoid tripping VLA warnings in stack
|
19 | 17 | * allocation usage).
|
| 18 | + * - Perform signed v unsigned type-checking (to generate compile |
| 19 | + * errors instead of nasty runtime surprises). |
| 20 | + * - Unsigned char/short are always promoted to signed int and can be |
| 21 | + * compared against signed or unsigned arguments. |
| 22 | + * - Unsigned arguments can be compared against non-negative signed constants. |
| 23 | + * - Comparison of a signed argument against an unsigned constant fails |
| 24 | + * even if the constant is below __INT_MAX__ and could be cast to int. |
20 | 25 | */
|
21 | 26 | #define __typecheck(x, y) \
|
22 | 27 | (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
|
|
26 | 31 | __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \
|
27 | 32 | is_signed_type(typeof(x)), 0)
|
28 | 33 |
|
29 |
| -#define __types_ok(x, y) \ |
30 |
| - (__is_signed(x) == __is_signed(y) || \ |
31 |
| - __is_signed((x) + 0) == __is_signed((y) + 0)) |
| 34 | +/* True for a non-negative signed int constant */ |
| 35 | +#define __is_noneg_int(x) \ |
| 36 | + (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0) |
| 37 | + |
| 38 | +#define __types_ok(x, y) \ |
| 39 | + (__is_signed(x) == __is_signed(y) || \ |
| 40 | + __is_signed((x) + 0) == __is_signed((y) + 0) || \ |
| 41 | + __is_noneg_int(x) || __is_noneg_int(y)) |
32 | 42 |
|
33 | 43 | #define __cmp_op_min <
|
34 | 44 | #define __cmp_op_max >
|
|
0 commit comments