Date: Tue, 13 Mar 2007 09:01:54 +0000 From: Poul-Henning Kamp <phk@phk.freebsd.dk> To: arch@freebsd.org Subject: <sys/queue.h> bikeshed proposal Message-ID: <39968.1173776514@critter.freebsd.dk>
next in thread | raw e-mail | index | archive | help
It has always bothered me that some of the TAILQ macros need to know the struct name of the header type. Many times where I could have avoided naming that structure, I had to, only to satisfy this weird craving of <sys/queue.h>. <sys/queue.h> needs the struct name TAILQ_LAST and TAILQ_PREV casts, what is potentially a pointer to an entry, to the header type, before it dereferences the backwards pointer. The validity of this cast depends critically on the layout of the entry struct and the header struct being identical with respect to the two pointers. So, if we have already assumed, that they have the same layout, why do the cast in the first place ? The following proof of concept patch shows, that you can implement these two macros without the cast to the header struct type. If we did this, we could eliminate the "headname" argument to TAILQ_FOREACH_REVERSE TAILQ_FOREACH_REVERS_SAFE TAILQ_LAST TAILQ_PREV Obviously this is bikeshed fodder, but given how big a help <sys/queue.h> is programming-wise, and given that those four macros are comparatively seldomly used, I will propose to remove this wart from <sys/queue.h> under the banner of computer science in general and suffer the minor backwards compatibility issues it will cause. Poul-Henning Index: queue.h =================================================================== RCS file: /home/ncvs/src/sys/sys/queue.h,v retrieving revision 1.68 diff -u -r1.68 queue.h --- queue.h 24 Oct 2006 11:20:29 -0000 1.68 +++ queue.h 13 Mar 2007 08:51:51 -0000 @@ -546,12 +546,12 @@ } while (0) #define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) + (*((head)->tqh_last->tqe_prev) #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + (*((elm)->field.tqe_prev->tqe_prev)) #define TAILQ_REMOVE(head, elm, field) do { \ QMD_TAILQ_CHECK_NEXT(elm, field); \ -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk@FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?39968.1173776514>