Reputation: 2528
While browsing Linux kernel source, I found hlist_bl_for_each_entry_rcu
macro.Below is its definition
for (pos = hlist_bl_first_rcu(head); \
pos && \
({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; }); \
pos = rcu_dereference_raw(pos->next))
This macro is used in __d_lookup()
to get the dentry. What I do not understand is the line
({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; });
It gets the tpos. What is the use of 1 here ? How to understand this condition in the for loop ?
Upvotes: 1
Views: 204
Reputation: 8657
If you were writing it macroless, it would probably look like this:
for (pos = hlist_bl_first_rcu(head); pos; pos = rcu_dereference_raw(pos->next)) {
tpos = hlist_bl_entry(pos, typeof(*tpos), member);
/* do something with pos and tpos */
}
For the macro, you would want to move tpos = hlist_bl_entry(pos, typeof(*tpos), member);
into the for (...)
, so the user only has to supply the for
block. In the macroless version, you want tpos
' value set every time pos
is non-NULL, thus you add it in the loop condition after a pos &&
:
pos && (tpos = hlist_bl_entry(pos, typeof(*tpos), member))
but now tops non-nullness becomes a loop condition, so you tell C to ignore the return value:
pos && ((tpos = hlist_bl_entry(pos, typeof(*tpos), member)), 1)
but kernel code is GNU C anyway, so you may use statement expressions instead:
pos && ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; })
Upvotes: 2