在gnu c 中,用括号将复合语句括起来也形成了表达式。他允许你在一个表达式内使用循环,跳转和局部变量。

一个复合语句是用大括号{}括起来的一组语句。在包含语句的表达式这种结构中,再用括号( )将大括号括起来,例如:
({ int y = foo (); int z;
  if (y > 0) z = y;
  else z = - y;
  z; })

就是一个合法表达式,用于计算foo( )函数返回值的绝对值。
在上面的复合语句中,最后的一句必须是一个以分号结尾的表达式。这个表达式代表了整个结构的值。如果你在大括号里的最后一句用的是其他的语句,则整个结构的返回类型为void,即没有合法的返回值。

这种特性使得宏定义变得更加安全(因为每个操作数都只被计算一次,例如++运算)。例如计算最大值通常在c语言中被定义为这样的宏:
#define max(a,b) ((a) > (b) ? (a) : (b))

但是其中的a和b可能会被计算两次,如果操作数带有副作用,则会产生错误的结果。在gnu c中,如果你知道了操作数的类型(假设为int),你可以这样安全的定义宏:
#define maxint(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b; })
语句内嵌在常量表达式(例如枚举类型),位域尺寸或静态变量初始化中是不允许的。如果你不知道操作数的类型,你也可以使用typeof来获得类型。
语句表达式内嵌在g++中并不支持,而且将来是否支持目前也不清楚(他们在某时被完全支持或者被抛弃掉,或者作为bug会一直存在)。就目前而言,语句内嵌表达式在默认情况下工作的并不好。


此外,在c++中语句内嵌表达式还存在很多语义问题。如果你希望在c++中用语句内嵌表达式来代替内联函数(inline function),对象的析构处理可能会让你惊讶。例如:
#define foo(a) ({int b = (a); b + 3; })
并不等同于
inline int foo(int a) { int b = a; return b + 3; }
具体而言,当传递给foo的表达式的会引入临时对象的生成的时候,这些临时对象的析构在用宏时会早于用函数的情况。

以上情况说明在用于c++代码的.h头文件中使用语句内联表达式并不是一个好主意。一些gnu c的库的某些版本中的使用语句内联表达式的头文件已经造成了这样的bug。

转载于:https://blog.51cto.com/nathanxu/6027

gcc对C语言的扩展:语句内嵌表达式(statement-embedded expression)相关推荐

  1. gcc对C语言的扩展:局部标签声明(Locally Declared Labels)

    每个语句内嵌表达式都是一个可以声明局部跳转标签的域.一个局部标签只是一个标识符:你可以使用通常的goto语句跳到它--但是只能在它所属的域内这么做. 一个局部标签的申明如下: __label__ la ...

  2. riot.js教程【四】Mixins、HTML内嵌表达式

    前文回顾 riot.js教程[三]访问DOM元素.使用jquery.mount输入参数.riotjs标签的生命周期: riot.js教程[二]组件撰写准则.预处理器.标签样式和装配方法: riot.j ...

  3. 在Java语言的if语句是什么表达式,if语句中的条件表达式中只能使用

    if语句中的条件表达式中只能使用关系或逻辑表达式吗?别的人十句话都不会伤到小编,但你的一句话就可以把小编伤得撕心裂肺. 不是,可以用任意表达式. if语句是指编程语言(包括c语言,C#,,java,V ...

  4. c语言编程软件出现问号,【C语言】if语句和问号表达式

    声明:本文属于原创,本人精心制作,欢迎大家转载,但转载请注明本文出自http://blog.163.com/kam_1993/ if语句是大多数程序语言中常用的一种语句.用于使程序有选择性的执行代码. ...

  5. php if 问号写法,【C语言】if语句和问号表达式

    声明:本文属于原创,本人精心制作,欢迎大家转载,但转载请注明本文出自http://blog.163.com/kam_1993/ if语句是大多数程序语言中常用的一种语句.用于使程序有选择性的执行代码. ...

  6. Go语言学习 二十一 内嵌

    本文最初发表在我的个人博客,查看原文,获得更好的阅读体验 在像Java这种语言中,有子类(或者继承)的概念,通过继承复用已有的功能或属性,与继承不同,Go中使用组合的方式来完成已有实现的复用,这种做法 ...

  7. for语句内嵌例题与个人理解

    例题1:画出一个高度为3的等腰三角形. 编写程序: #include<stdio.h> main() { int a,b,c,h; h=3;                         ...

  8. 塞班、libc.lib、系统错误-1、KErrNotFound、内嵌sis、embedded sis

    使用了libc.lib诸函数后,模拟器上没问题,真机上报错"系统错误-1",可能是缺少pips_s60_1_6_ss.sis运行库.在pkg文件中将其打包进去. ;注意:把pips ...

  9. (转)C语言家族扩展

    (转)C语言家族扩展 翻译: 5.1--5.6 林峰 5.7--5.20 董溥 5.21--5.26 王聪 5.27--5.34 刘洋 5.35--5.43 贾孟树 致谢:感谢陈老师指出其中的一些错误 ...

最新文章

  1. python处理html的table标签
  2. STL源代码分析(ch2 内存分配)uninitialized_fill_n
  3. 团队任务3:软件设计与开发准备
  4. LeetCode之Rotate Array
  5. 简述垃圾对象产生_使用零垃圾创建数百万个对象
  6. VMware ubuntu 上网
  7. 脚本两则--用于快速部署HADOOP,SPARK这些(特别是VM虚拟机模板部署出来的)。。...
  8. python 变量类型list_Python基础变量类型——List浅析-阿里云开发者社区
  9. 程序员对学历高吗?毕业是考研还是实习?
  10. ip、url威胁情报库(开源)
  11. d.php xfso_centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总...
  12. 超强性能,秒级存储,华为云GeminiDB for Cassandra 正式商用了
  13. php session实现原理
  14. 比尔·盖茨退出微软公司董事会;苹果 WWDC、微软 Build 大会均改为线上举办;Rust 1.42.0 发布| 极客头条...
  15. java int在那个包_int intValue()
  16. SQlite数据库的C编程接口(二) 数据库连接 ——《Using SQlite》读书笔记
  17. grads 相关系数_GrADS实习报告6
  18. Code For Better 谷歌开发者之声——Flutter - Google 开源的移动 UI 框架
  19. ios android与wp,在iOS与Android间选择WP
  20. vue webapp之music(六)利用axios与后端接口代理请求歌单推荐数据

热门文章

  1. C++ 多态在异常中的使用
  2. android保持服务不休眠,Android开发保持屏幕常亮和CPU不休眠唤醒状态
  3. vi中如何实现批量替换
  4. 【汇编语言】王爽 - 内中断复习
  5. mysql error -1_【Mysql】SQLException: Got error -1 from storage engine 问题解决!
  6. malloc、calloc、realloc和alloca各种的区别
  7. jQuery源码分析--Event模块(1)
  8. 安装CoreOS到磁盘
  9. 英语语法学习2--句子的成分
  10. (教学思路 C#之类五)类的分类(静态类、实例类、嵌套类、结构、简单的抽象类、简单的密封类)...