【问题标题】:Purpose of Curly Brace Usage of C Code found in Linux (include/linux/list.h)?在 Linux (include/linux/list.h) 中找到的 C 代码的大括号用法?
【发布时间】:2013-06-05 14:33:40
【问题描述】:

我在 Linux (include/linux/list.h) 中遇到了以下代码。我对第 713 行感到困惑。特别是,我不明白 ({ n = pos->member.next; 1; })。

花括号在做什么?为什么这个语句中有一个“1”?

如果有人能解释这一特定行,将不胜感激。请注意,我不需要解释链接列表和#defines 的工作原理等。

704 /**
705  * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
706  * @pos:        the type * to use as a loop cursor.
707  * @n:          another &struct hlist_node to use as temporary storage
708  * @head:       the head for your list.
709  * @member:     the name of the hlist_node within the struct.
710  */
711 #define hlist_for_each_entry_safe(pos, n, head, member)                 \
712         for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\
713              pos && ({ n = pos->member.next; 1; });                     \
714              pos = hlist_entry_safe(n, typeof(*pos), member))
715 

【问题讨论】:

  • ({ /* code */ }) 是一个 GNU 扩展,一个语句表达式。大括号内的代码被执行,其值为里面最后一个表达式的值。

标签: c linux linked-list curly-braces


【解决方案1】:

这是一个语句表达式。它是gcc extension,根据文档6.1 Statements and Declarations in Expressions

复合语句中的最后一件事应该是一个表达式,后跟一个分号;这个子表达式的值作为整个构造的值。

在这种情况下,对于代码:

({ n = pos->member.next; 1; })

值为1。根据文档:

此功能在使宏定义“安全”方面特别有用(因此它们对每个操作数只计算一次)。

它给出了这个例子,没有使用语句表达式

#define max(a,b) ((a) > (b) ? (a) : (b))

与这个 安全 版本相比,需要注意的是您知道操作数的类型:

#define maxint(a,b) \
   ({int _a = (a), _b = (b); _a > _b ? _a : _b; })

这是众多gcc extensions used in the Linux kernel之一。

【讨论】:

  • @Will 任何有副作用的东西都有被应用两次的风险。例如:max(a++,b) 将扩展为两个 a++,这与常规函数调用不同。
【解决方案2】:

这是一个称为statement expression 的GNU 语言扩展;这不是标准的 C。

【讨论】:

    猜你喜欢
    • 2021-07-31
    • 1970-01-01
    • 2011-02-24
    • 2016-10-02
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多