{()}的用法

@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


版权声明:本文为qq_34915586原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。