Just do this: printk("count: " COUNTER_T_FORMAT_SPECIFIER "things", c);
Just do this: printk("count: " COUNTER_T_FORMAT_SPECIFIER "things", c);
printk("subtotals: a %d, b %d, c %d, total %d\n", a,b,c,a+b+c);
you have
printk("subtotals: a " COUNTER_T_FORMAT_SPECIFIER ", b " COUNTER_T_FORMAT_SPECIFIER ", c " COUNTER_T_FORMAT_SPECIFIER ", total " COUNTER_T_FORMAT_SPECIFIER "\n", a,b,c,a+b+c);
and soon you (1) can't read your code at all because 60% of it is shouty stuff in your calls to printk and (2) even the printk calls are awkward to read because your eyes have to skip over all the shouty stuff to work out what the output's actually going to look like.
(Perhaps that was your point, in which case I apologize for thinking it needed spelling out more explicitly.)
However, if printk would be declared with __attribute__((format(printf, 1, 2)) (I don't know if it is), gcc would warn if the format string contains specifiers which do not match the given types, regardless of any typedefs.