On Thu, 21 Mar 2013, Taylor R Campbell wrote:
/* typeof-free roundup2/rounddown2 */ #define roundup2(x, m) (((x) + ((m) - 1)) & ~((m) - 1 + ((x) - (x)))) #define rounddown2(x,m) ((x) & ~((m) - 1 + ((x) - (x)))) /* multiple-evaluation-free roundup2/rounddown2 */ #define roundup2(x, m) ((((x) - 1) | ((m) - 1)) + 1) #define rounddown2(x,m) ((x) &~ ((typeof(x))((m) - 1))) #define offsetin(s, f) (((const char *)&(s).f) - ((const char *)&(s))) #define container_of(p, t, f) \ ((void)sizeof((p) - \ &((t *)(((char *)(p)) - offsetof(t, f)))->f), \ ((t *)(((char *)(p)) - offsetof(t, f))))
Fixing roundup2 seems like a good idea, and I have no objection to adding rounddown2.
I don't really see the point of offsetin -- if you have a struct that ends with an array of 1 element, but you want to allocate enough space for the struct plus an array of >1 elements, then why not just do the arithmetic without a macro, and if you do need a macro, then why not give it a name that sounds more like "sizeof"?
I also don't see the point of container_of -- why not redesign the code so that the the inner struct has a pointer to the outer struct?
Please don't evaluate macro arguments more than once, except in macros whose names are ALL_CAPS.
Since it's not standard C, I think __typeof__ would be preferable to typeof. My tests show that it's available in gcc, clang, and pcc.
--apb (Alan Barrett)