[Swan-dev] FOR_EACH_LIST_ENTRY_

D. Hugh Redelmeier hugh at mimosa.com
Sun Dec 9 17:59:17 UTC 2018


I find this macro almost impenetrable.

I think that this is mainly due to it being contorted to make it look like 
the head of a for statement: the code to be iterated over follows the 
macro invocation.

If we passed that code to the macro, I think that the macro could be a lot 
simpler and clearer.

Here's my stab at it.  Perhaps I've misunderstood something about the 
original and thus may have it wrong.

Comments?

==== original ====

#define FOR_EACH_LIST_ENTRY_(HEAD, DATA, NEXT)				\
									\
	/* set head_ = HEAD (evaluate once) */				\
	for (struct list_head *head_ = HEAD;				\
	     head_ != NULL; head_ = NULL)				\
									\
		/* set entry = head.NEXT; skip empty */			\
		for (struct list_entry *entry_ = head_->head.NEXT;	\
		     entry_ != &head_->head; entry_ = &head_->head)	\
									\
			/* DATA = ENTRY->data; ENTRY = ENTRY->NEXT */	\
			for (DATA = (typeof(DATA))entry_->data,		\
				     entry_ = entry_->NEXT;		\
			     DATA != NULL;				\
			     DATA = (typeof(DATA))entry_->data,		\
				     entry_ = entry_->NEXT)

==== replacement ====

/* traverse doubly-linked list
 *
 * The HEAD entry is a dummy.
 * It exists even when the list is empty.
 * It is distinguished by a NULL data field.
 */

#define FOR_EACH_LIST_ENTRY_(head, DATA, NEXT, BODY)	\
	for (struct list_entry *entry_ = (HEAD); ; ) {	\
		entry_ = entry_->NEXT;	\
		DATA = (typeof(DATA))entry_->data;	\
		if (DATA == NULL)	\
			break;	\
		{ BODY ; }	\
	}


More information about the Swan-dev mailing list