The joy of max()

max()

LWN recently looked at the kernel's max() macro and the effort put into ensuring that it would evaluate to a "constant expression" as seen by the compiler. After a number of iterations, it would appear that the problem has been solved. For your reading pleasure, here is the new form of, extracted from the patch posted by Kees Cook:

#define __typecheck(x, y) \ (!!(sizeof((typeof(x)*)1 == (typeof(y)*)1))) #define __is_constant(x) \ (sizeof(int) == sizeof(*(1 ? ((void*)((long)(x) * 0l)) : (int*)1))) #define __no_side_effects(x, y) \ (__is_constant(x) && __is_constant(y)) #define __safe_cmp(x, y) \ (__typecheck(x, y) && __no_side_effects(x, y)) #define __cmp(x, y, op) ((x) op (y) ? (x) : (y)) #define __cmp_once(x, y, op) ({ \ typeof(x) __x = (x); \ typeof(y) __y = (y); \ __cmp(__x, __y, op); }) #define __careful_cmp(x, y, op) \ __builtin_choose_expr(__safe_cmp(x, y), \ __cmp(x, y, op), __cmp_once(x, y, op)) #define max(x, y) __careful_cmp(x, y, >)

The above definitions should, of course, be immediately obvious to any LWN reader. For those who want an extra hint or two, though, the patch posting includes a few explanatory comments.

