在浏览Linux内核源代码时,我发现了hlist_bl_for_each_entry_rcu

for (pos = hlist_bl_first_rcu(head);                            \
                pos &&                                                  \
                ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; }); \
                pos = rcu_dereference_raw(pos->next))

此宏用于__d_lookup()中以获取dentry。我不明白的是
({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; });
它得到了TPO。这里1有什么用?如何理解for循环中的这种情况?

最佳答案

如果你写的是无宏的,可能会是这样的:

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 */

}

对于宏,您需要将tpos = hlist_bl_entry(pos, typeof(*tpos), member);移动到for (...)中,因此用户只需提供for块。在无宏版本中,您希望每次tpos为非空时都设置pos'值,因此在pos &&之后将其添加到循环条件中:
pos && (tpos = hlist_bl_entry(pos, typeof(*tpos), member))

但是现在tops不为零变成了一个循环条件,所以你告诉Cignore the return value
pos && ((tpos = hlist_bl_entry(pos, typeof(*tpos), member)), 1)

但是内核代码无论如何都是GNU C,所以您可以使用statement expressions代替:
pos && ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; })

关于c - 了解Linux内核中的hlist_bl_for_each_entry_rcu宏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49839170/

10-12 06:23