# Why we need `({...;1;})` in `hlist_for_each_entry_safe`? While examining the implementation of [ping](https://github.com/torvalds/linux/blob/master/net/ipv4/ping.c) in Linux, I noticed that `sk_for_each` is essentially `hlist_for_each_entry`, leading me to discover the use of such an expression in `hlist_for_each_entry_safe`. ```c= #define hlist_for_each_entry(pos, head, member) \ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ pos; \ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) #define hlist_for_each_entry_safe(pos, n, head, member) \ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ pos && ({ n = pos->member.next; 1; }); \ pos = hlist_entry_safe(n, typeof(*pos), member)) ``` ## What is the value of `({...;1;})` "[Statements and Declarations in Expressions](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html)" section of the GNU GCC manual. > The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct. (If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.) The value represented by the entire expression is `1`, so the value represented by `pos && ({ n = pos->member.next; 1; })` is equivalent to `pos && 1`. ## Why? The purpose of this macro is to traverse a Linked List starting from `head`, but the nodes of this Linked List are contained within another structure. The nodes in this structure point to nodes in the next structure rather than the structure itself. Therefore, we need to extract the node from the next structure first in order to obtain the address of the next entry through `hlist_entry_safe` (which is almost equivalent to `container_of`). ## Why we need the safety version? The version of this safe is designed to handle the possibility of elements being removed. If `pos` is removed, directly calling `pos->member.next` would result in accessing `next` from a `NULL` pointer, which is an invalid operation. Therefore, if it can be guaranteed that during this traversal process, no elements will be deleted, then the safe version is not necessary.