#define max(x,y) ({ \
    typeof(x) _x = (x); \
    typeof(y) _y = (y); \
    (void) (&_x == &_y); \

_x > _y ? _x : _y; })

在这个宏中,花括号里表达式的值为最后一条语句的值,然后用小括号将大括号括起来就可以给其他变量赋值了。当红语句中的最外层小括号不用的话,也就是如果这个宏语句改为如下时:

#define max(x,y)  { \
    typeof(x) _x = (x); \
    typeof(y) _y = (y); \
    (void) (&_x == &_y); \

_x > _y ? _x : _y; }

就会出现错误。具体为什么会出现这样的情况本人也不是很清楚。但在网上看到一个这样的介绍:

gcc的扩展用法,标准C++不支持。



它相当于是扩展了primary-expression

primary-expression:

     identifier

     constant

     string-literal

     ( expression )



   GNU extensions:



   primary-expression:

     __func__

       (treated as a keyword in GNU C)

     __FUNCTION__

     __PRETTY_FUNCTION__

     ( compound-statement )        // compound-statement 就是花括号语句

     __builtin_va_arg ( assignment-expression , type-name )

     __builtin_offsetof ( type-name , offsetof-member-designator )

     __builtin_choose_expr ( assignment-expression ,

                             assignment-expression ,

                             assignment-expression )

     __builtin_types_compatible_p ( type-name , type-name )

6 Extensions to the C Language Family

GNU C provides several language features not found in ISO standard C. (The ‘-pedantic’

option directs GCC to print a warning message if any of these features is used.) To test for

the availability of these features in conditional compilation, check for a predefined macro

__GNUC__, which is always defined under GCC.

These extensions are available in C and Objective-C. Most of them are also available in

C++. See Chapter 7 [Extensions to the C++ Language], page 581, for extensions that apply

only to C++.

Some features that are in ISO C99 but not C90 or C++ are also, as extensions, accepted

by GCC in C90 mode and in C++.



6.1 Statements and Declarations in Expressions

A compound statement enclosed in parentheses may appear as an expression in GNU C.

This allows you to use loops, switches, and local variables within an expression.

Recall that a compound statement is a sequence of statements surrounded by braces; in

this construct, parentheses go around the braces. For example:

({ int y = foo (); int z;

if (y > 0) z = y;

else z = - y;

z; })

is a valid (though slightly more complex than necessary) expression for the absolute value

of foo ().

The last thing in the compound statement should be an expression followed by a semi-

colon; the value of this subexpression serves as the value of the entire construct. (If you use

some other kind of statement last within the braces, the construct has type void, and thus

effectively no value.)

This feature is especially useful in making macro definitions “safe” (so that they evaluate

each operand exactly once). For example, the “maximum” function is commonly defined

as a macro in standard C as follows:

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

But this definition computes either a or b twice, with bad results if the operand has side

effects. In GNU C, if you know the type of the operands (here taken as int), you can define

the macro safely as follows:

#define maxint(a,b) \

({int _a = (a), _b = (b); _a > _b ? _a : _b; })

Embedded statements are not allowed in constant expressions, such as the value of an

enumeration constant, the width of a bit-field, or the initial value of a static variable.

If you don’t know the type of the operand, you can still do this, but you must use typeof

(see Section 6.6 [Typeof ], page 296).

In G++, the result value of a statement expression undergoes array and function pointer

decay, and is returned by value to the enclosing expression. For instance, if A is a class,

then290 Using the GNU Compiler Collection (GCC)

A a;

({a;}).Foo ()

will construct a temporary A object to hold the result of the statement expression, and that

will be used to invoke Foo. Therefore the this pointer observed by Foo will not be the

address of a.

Any temporaries created within a statement within a statement expression will be de-

stroyed at the statement’s end. This makes statement expressions inside macros slightly

different from function calls. In the latter case temporaries introduced during argument

evaluation will be destroyed at the end of the statement that includes the function call. In

the statement expression case they will be destroyed during the statement expression. For

instance,

#define macro(a) ({__typeof__(a) b = (a); b + 3; })

template<typename T> T function(T a) { T b = a; return b + 3; }

void foo ()

{

macro (X ());

function (X ());

}

will have different places where temporaries are destroyed. For the macro case, the tem-

porary X will be destroyed just after the initialization of b. In the function case that

temporary will be destroyed when the function returns.

These considerations mean that it is probably a bad idea to use statement-expressions of

this form in header files that are designed to work with C++. (Note that some versions of

the GNU C Library contained header files using statement-expression that lead to precisely

this bug.)

Jumping into a statement expression with goto or using a switch statement outside the

statement expression with a case or default label inside the statement expression is not

permitted. Jumping into a statement expression with a computed goto (see Section 6.3

[Labels as Values], page 291) yields undefined behavior. Jumping out of a statement ex-

pression is permitted, but if the statement expression is part of a larger expression then

it is unspecified which other subexpressions of that expression have been evaluated except

where the language definition requires certain subexpressions to be evaluated before or after

the statement expression. In any case, as with a function call the evaluation of a statement

expression is not interleaved with the evaluation of other parts of the containing expression.

For example,

foo (), (({ bar1 (); goto a; 0; }) + bar2 ()), baz();

will call foo and bar1 and will not call baz but may or may not call bar2. If bar2 is called,

it will be called after foo and before bar1

c语言中用括号将花括号括起来给变量赋值相关推荐

  1. shell脚本中的几个括号总结(小括号/大括号/花括号)

    [转载]shell脚本中的几个括号总结(小括号/大括号/花括号) (2011-10-08 21:23:34) 转载▼ 标签: 杂谈 分类: linux shell脚本中的几个括号总结(小括号/大括号/ ...

  2. 小括号与花括号小括号与花括号

    scala雾中风景(2): 小括号与花括号 2条回复 下面的问题,表面上看是小括号与花括号的问题. // map方法这样写不能编译通过 scala> List(2).map( case 2 =& ...

  3. Scala之小括号和花括号(Parentheses Crurly Braces)

    文章目录 在调用函数时 如果你要调用的函数有两个或两个以上的参数,那么你只能使用"小括号" 如果你要调用的函数只有单一参数,那么"通常"情况下小括号和花括号是可 ...

  4. c语言循环语句中花括号的作用,c语言中用括号将花括号括起来给变量赋值

    #define max(x,y) ({ \ typeof(x) _x = (x);\ typeof(y) _y = (y);\ (void) (&_x == &_y);\ _x > ...

  5. c语言错误出在花括号上,初学者在学习c语言编程过程中常出现的错误分析

    在高校经常中开设的第一科关于程序设计的语言就是C语言,这种语言有很多优势,比如说使用比较灵活,功能比较强大,可以用于编写程序.软件,但是对于初学者来说, 1 0 8 应用方法论 22第霸 0赫 6乱 ...

  6. c语言for可以不用花括号吗,c-使用不带花括号的switch语句是否有用?

    这是由Dennis Ritchie在1972年进行的第一个C编译器工作期间编写的示例. 我刚刚链接到的页面底部的c02.c模块包括 easystmt() { extern peeksym, peekc ...

  7. shell 中的括号(小括号,花括号)

    链接:http://my.oschina.net/xiangxw/blog/11407 在这里我想说的是几种shell里的小括号,大括号结构和有括号的变量,命令的用法,如下: 1.${var}  2. ...

  8. c语言中复合语句不用花括号,【单选题】C语言中,可将一系列语句置于( )从而构成复合语句。 A. 一对尖括号\ \之间 B. 一对圆括号\( )\之间 C. 一对花括号 { } 之间 D....

    [单选题]C语言中,可将一系列语句置于( )从而构成复合语句. A. 一对尖括号\"< >\"之间 B. 一对圆括号\"( )\"之间 C. 一对花 ...

  9. 英文如何区分小括号和花括号

    小括号:parentheses bracket ( ) 中括号:bracket [ ] 大括号:curly braces { }

最新文章

  1. 深度学习图像搜索与识别
  2. Windows 10:开机显示C:\WINDOWS\system32\config\systemprofile\Desktop不可用 的解决方法
  3. Asp默认的上传文件大小限制是200K
  4. ICMP Internet控制报文协议
  5. linux基础命令(-)
  6. dos命令测试网络连通情况
  7. 卸载oracle11g步骤_oracle11g完全卸载步骤来了,你真的不来看看吗
  8. 彻底删除0KB顽固文件或文件夹的方法
  9. 入行数据科学,仅需6步
  10. python如何合并txt文件_Python实现将目录中TXT合并成一个大TXT文件的方法
  11. TCP/IP协议详解:IP、ARP、RARP、ICMP、IGMP
  12. python 当天零点的时间戳
  13. 专升本英语——语法知识——基础语法——第一节 名词和代词【学习笔记】
  14. 作为老师的一些思考(二)
  15. 2022年中级经济师考试中级人力资源练习题及答案
  16. 关于 国产麒麟系统编译Qt项目是报错:error: cannot find -lGL 的解决方法
  17. Transflow:Quake 是如何构建以 DSL 为核心的低代码系统?
  18. 企业知识管理平台的作用及功能
  19. Mac苹果电脑 安装virtualBox
  20. CCC产品认证的标准

热门文章

  1. LAS语音识别框架发展简述
  2. python身份证号码共18位_18位身份证校验
  3. 基于Springboot的网上商城
  4. SpringBoot性能优化方案
  5. 【Banana PI Leaf S3开发板试用体验】MicroPython环境搭建
  6. 前端必备知识储存——HTML篇一(面试常考)
  7. 深度学习究竟是什么,举个例子解释一下
  8. 计算机app无法删除,电脑软件卸载不掉怎么办?软件删除不掉解决技巧
  9. vm虚拟服务器无法启动,win10升级后vm虚拟主机无法启动的解决办法
  10. RevitAPI: 如何判断天花板的族类型是否是复合结构