On Fri, Dec 11, 2015 at 08:49:24AM +0100, Rasmus Villemoes wrote: > union delayed_call_fn { > void (*fn)(void *); > void (*kfree_like)(const void *); > } __attribute__((__transparent_union__)); > > void > set_delayed_call(struct delayed_call *call, union delayed_call_fn u, void > *arg) > { > call->fn = u.fn; > call->arg = arg; > }
Yecchhhh... If we are into that kind of gccisms, I'd rather use __builtin_choose_expr/__builtin_types_compatible_p. At least that is used elsewhere in the kernel; __transparent_union__ kludge isn't. Sure, it means having set_delayed_call() a macro, but IMO it's less nasty that way... FWIW, another possibility is to have #define CLOSURE_CALLBACK(f,type) \ static inline void __closure_##f(void *p) {return f((type)p);} #define set_delayed_type(call, f, arg) \ sizeof(f(arg),0), \ __set_delayed_type(call, __closure_##f, (void *)arg) That could be reused for timers with typechecking - we have a lot of timer callbacks that start with casting the argument (unsigned long, not void *, but that's not a big deal) to whatever it is that callback really wants, with setup_timer() callers explicitly casting that whatever the callback really wants to unsigned long. Which, of course, defeats the typechecking by both cc(1) and sparse(1)... I still hope for better solution, though... Comments? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/