> > Another possibility is a macro like > > > > #define field_at_offset(base, offset, type) \ > > ((type) (((char *) (base)) + (offset))) > > > > so that you can do > > > > *field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET) = NULL; > > *field_at_offset(void ***, elm, (entry) + QTAILQ_PREV_OFFSET) = > > *field_at_offset(void ***, head, QTAILQ_LAST_OFFSET); > > **field_at_offset(void ***, head, QTAILQ_LAST_OFFSET) = (elm); > > *field_at_offset(void ***, head, QTAILQ_LAST_OFFSET) = > > field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET); > > The thing is that we don't know type at all. So only the offset values > is used. This is intended for QTAILQ of any type.
Sure, my code is identical to yours---just with more macros for readability, and a little more type-safe. Another possibility: #define QTAILQ_RAW_NEXT(elm, entry) \ (*field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET)) #define QTAILQ_RAW_PREV(elm, entry) \ (*field_at_offset(void ***, elm, (entry) + QTAILQ_PREV_OFFSET)) #define QTAILQ_RAW_LAST(head) \ (*field_at_offset(void ***, head, QTAILQ_LAST_OFFSET)) QTAILQ_RAW_NEXT(elm, entry) = NULL; QTAILQ_RAW_PREV(elm, entry) = QTAILQ_RAW_LAST(head); *QTAILQ_RAW_LAST(head) = (elm); QTAILQ_RAW_LAST(head) = &QTAILQ_RAW_NEXT(elm, entry); Thanks, Paolo > Thanks, > Jianjun > > > > > or something like that (note that I've always used the same type for > > next and last, by the way). > > > > Paolo > > > >