2013-06-09 5 views
4

Я столкнулся с следующим кодом в Linux (include/linux/list.h). Я запутался в строке 713. В частности, я не понимаю ({n = pos-> member.next; 1;}).Назначение фигурной скобки Использование кода C в Linux (include/linux/list.h)?

Что такое фигурные скобки? Почему в этом заявлении есть «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 
+3

'({/ * code * /})' является расширением GNU, выражением оператора. Выполняется код в фигурных скобках, а значение - это значение последнего выражения внутри. –

ответ

6

Это выражение выражения . Это 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.

+0

Не быть аргументированным, а просто любопытным: можете ли вы привести пример аргументов, переданных в 'max (a, b) ((a)> (b)? (A): (b))', который сделал бы это выражение небезопасным? – Will

+3

@ Будут все, что имеет побочные эффекты, связанные с тем, что они применяются дважды. Например: 'max (a ++, b)' будет расширяться до двух a ++, в отличие от обычного вызова функции. – Trillian

+0

@ Триллиан А, да. D'о! Благодарю. – Will