求一个内核宏的解释:hlist_nulls_for_each_entry

Ask for explanation of a kernel macro: hlist_nulls_for_each_entry

我对 Linux 内核函数定义感到困惑。 hlist_nulls_for_each_entry定义为for循环,最容易理解的信息。

#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)

虽然我看不懂下面这句话,为什么作者要加上; 1; 到最后。为什么不把句子 tpos = hlist_nulls_entry(pos, typeof(*tpos), member) 移到下面的 pos = pos->next.

 ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1;});

这是复合语句。最后 1 在那里,因此语句块的值计算为 1,使条件为真。

来自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.

在这里,不管 tpos 的赋值是什么,我们都想执行 for 循环。这就是那里有 1; 的原因。循环将在指定的其他条件下停止,即 (!is_a_nulls(pos)).

是的,您也可以使用递增操作将其移动到 - 由逗号运算符分隔。我们也可以格式化循环来做到这一点。但请记住,这里我们也是 运行 初始值的循环,因此我们需要在增量完成之前使用它。

请注意 - 这是一个 gcc 扩展。 C 标准不提供这个。这意味着它不是一个可移植的解决方案。如果您将它写在相同的旧 for 循环块中,那么基于可移植性,您会很高兴。