Reputation: 734
I am confused with a Linux kernel function definition. hlist_nulls_for_each_entry is defined as a for loop, and it's easy to understand the most info。
#define hlist_nulls_for_each_entry(tpos, pos, head, member) \
for (pos = (head)->first; \
(!is_a_nulls(pos)) && \
({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1;}); \
pos = pos->next)
While I can't understand the following sentence, why do the author add ; 1; to the end. Why not move the sentence tpos = hlist_nulls_entry(pos, typeof(*tpos), member) to following of pos = pos->next .
({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1;});
Upvotes: 1
Views: 129
Reputation: 30926
This is a compound statement. Last 1
is there so that the value of the statement block evaluates to 1 making the condition true.
From the documentation
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.
Here irrespective of what turns out to be the assigned value of tpos
we want to execute the for
loop. That's why there is 1;
there. The loop will stop on the other condition specified, which is (!is_a_nulls(pos))
.
Yes you can move it to with the incremement operation also -separated by commma operator. We can format the loop to do that also. But remember that here we are running the loop for initial value also, so we need to work with it before incrememnt is done.
Note that - this is a gcc extension. C standard doesn't offer this. This means it is not a portable solution. If you write it in same old for loop block you will be good to go based on portability.
Upvotes: 3