On 01/13/2012 06:05 PM, Paolo Bonzini wrote: > I think it's not entirely correct because the cast in QTAILQ_PREV and > QTAILQ_FOREACH_REVERSE does not look like valid ANSI C. No matter how > hard I look I admit I cannot figure out how it works, but anyway I > suspect it can be changed to ANSI C using typeof if one was bitten by > it. So removing QCIRCLEQ is not a bad idea anyway.
Ah, got it. Here are two ways to rewrite it using typeof (not exactly ANSI C of course, but perhaps somewhat more aliasing friendly). #define QTAILQ_PREV(elm, next) \ (*(((__typeof__((elm)->next) *)((elm)->next.tqe_prev))->tqe_prev)) #define Q_TAILQ_PREV(tqe) \ ((__typeof__(tqe) *)((tqe).tqe_prev)) #define QTAILQ_PREV(elm, next) \ (Q_TAILQ_PREV(*Q_TAILQ_PREV((elm)->next))->tqe_next) It's treating the TAILQ as a half-linear (forwards), half-circular (backwards) list. Doing two backwards accesses and one forwards access ensures that the last access is always on a pointer rather than a pointer-to-pointer. Clever. Paolo