News for hackers. Stuff that matters.
Re:ISO C is increasingly moronic by comex on Tuesday December 20, 2011 @04:00PM (#3375141)
I don't see this as particularly monstrous - it's reasonably succinct, and in this case a macro implementation does the job just as well as a built-in linked list would, and with much more flexibility.

    #define VTAILQ_INSERT_BEFORE(listelm, elm, field) do {              \
        (elm)->field.vtqe_prev = (listelm)->field.vtqe_prev;            \
        VTAILQ_NEXT((elm), field) = (listelm);                          \
        *(listelm)->field.vtqe_prev = (elm);                            \
        (listelm)->field.vtqe_prev = &VTAILQ_NEXT((elm), field);        \
    } while (0)
(I don't understand why it uses VTAILQ_NEXT((elm), field) instead of what it expands to, (elm)->field.vtqe_next - that would make it more obvious what's going on by paralleling the use of vtqe_prev - but that's the fault of the macro implementation.)
Re:ISO C is increasingly moronic by aliguori on Tuesday December 20, 2011 @04:08PM (#3375170)
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.

Re:ISO C is increasingly moronic by comex on Tuesday December 20, 2011 @06:07PM (#3375606)
> 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.

Re:ISO C is increasingly moronic by tkahn6 on Tuesday December 20, 2011 @06:53PM (#3375746)
Can anyone explain why this needs to be a macro? What does this get you over a plain function?
Re:ISO C is increasingly moronic by tptacek on Tuesday December 20, 2011 @11:25PM (#3376348)
The idiomatic way you'd express a generic tailq in C with functions is with void-stars, which cost 4-8 bytes and incur the costs of indirecting through another memory address and, probably, of allocating lots of fiddly little structs at random times.

The macro version expresses the same generalized logic but embeds the link pointers in the structure you're queueing.

Re:ISO C is increasingly moronic by tkahn6 on Wednesday December 21, 2011 @06:27AM (#3377166)
Thanks! Helpful as always.
Re:ISO C is increasingly moronic by saurik on Tuesday December 20, 2011 @07:47PM (#3375890)
The "field" argument cannot be passed as an argument to a normal function in C. FWIW, you could pass it as an argument in C++ (which supports pointers to members), but in C++ there are numerous better ways of implementing this.
Re:ISO C is increasingly moronic by jedbrown on Tuesday December 20, 2011 @07:46PM (#3375889)
It's intended to be used with lists with different payloads, all "inheriting" fields from a standard list structure (usually another macro expansion).