@TOC
kernel 经常出现的({})
本文跟编译原理的语法分析有关,需要清楚语句和表达式的两个基本概念
Statements 语句
The statements of a C program control the flow of program execution.
包括
- Expression Statement:
x = ( y + 3 ); /* x is assigned the value of y + 3 */
x++; /* x is incremented */
x = y = 0; /* Both x and y are initialized to 0 */
proc( arg1, arg2 ); /* Function call returning void */
y = z = ( f( x ) + 3 ); /* A function-call expression */
- labeled-statement:identifier : statement
- compound statement 复合语句:由{}组成的
- selection-statement:if ( expression ) statement
- iteration-statement: do statement while ( expression ) ;
Expressions 表达式
An “expression” is a sequence of operators and operands that performs any combination of these actions:
- Computing a value from the operands.
- Designates an object or function
- Generates side effects
以下是在gcc官方文档.关于({})的说明,下面是原文翻译
6.1 表达式中的语句和声明
在GNU C语法中,用大括号包围的复合语句可以看成是表达式。你可以在这样的复合语句表达式里使用loops,switch,局部变量等表达式。回想一下,复合语句是由大括号包围的语句序列。(这里原文是;号,改为。号)下面有一种这样的结构,小括号包围住大括号(复合语句)。例如有这样的写法:
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
这是个有效的表达式(虽然看起来有些复杂),表达式的结果是获得foo()的绝对值。
复合语句中最后一定要是带“;”符号的表达式,它(以及它的子表达式)的值就是整个复合语句结构的结果。(如果你用其他形式的语句作为结尾的语句,那么这个{}大括号所表示的表达式的结果就是个void,因此,实际上也就没有结果值。)
这个特征用在宏定义中非常有用和安全(例如,这个特征对每个操作数精确求值一次完成)。举个例子,maximum 这个求最大值的函数在标准C语法中经常被定义为宏。
#define max(a,b) ((a) > (b) ? (a) : (b))
但是这个定义会计算a或b两次,并且如果a或b有副作用的话会产生错误的答案。在GNU C中,如果你知道操作数的类型(这里是int),你可以通过定义如下的宏避免这个错误
#define maxint(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b; })
但是注意这种方式的变量声明会被屏蔽掉(variable shadowing),因此使用max宏会得到正确的答案,
int _a = 1, _b = 2, c;
c = max (_a, _b);
但是下面的方式却会得到错误的答案
int _a = 1, _b = 2, c;
c = maxint (_a, _b);
如果你不清楚操作数的类型,你可以使用 typeof or __auto_type