There are many things horrible about it. Its arguments are evaluated many times which is different than what you would expect. The fact that you have to pass field is just plain clumsy.
C could benefit tremendously from a parameterized type mechanism.
> Its arguments are evaluated many times which is different than what you would expect.
True - I would like to see the GCC extension that allows this to be done safely standardized, or improved.
> The fact that you have to pass field is just plain clumsy.
Sort of. I think the C trick of having linked list pointers inside the struct rather than the usual external wrapper is quite nice: it has good performance (especially in cases with multiple lists, to the extent that Boost has Boost.Intrusive even though it's really gross in C++), and explicitly codifying "struct A is a member of exactly one A-list" makes things feel simpler to me. You could have some kind of magic object in the list head that defines which member field it uses, but I don't know if that's worth the downside of the implementation no longer being trivial (and thus easy to understand).
I mean, there are lots of generally ugly points to C macros, but I have yet to see a better option for this kind of stuff that doesn't sacrifice either performance or simplicity - although the macro language itself could certainly be vastly improved.
C could benefit tremendously from a parameterized type mechanism.