找回密码
 注册
关于网站域名变更的通知
查看: 462|回复: 1
打印 上一主题 下一主题

gcc对C语言的扩展:语句内嵌表达式

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-3-11 17:47 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
0 s" S8 C. ?6 \2 R4 d
gcc对C语言的扩展:语句内嵌表达式(statement-embedded expression)0 ?& v3 D" N9 x# [
今天突然发现了这个新的语法现象,现转载如下。感觉到目前为止,内嵌表达式有点像“鸡肋”,不好用但又确实有其好处。不过还是不建议使用,现转载的目是希望以后大家在看系统代码时遇到这种现象能知其所以原,出现BUG也好应对。
, \# t8 Y* ~4 A. b% a" L7 }8 n  C  T6 }$ L; j3 q) F

& H9 H: y( ]. d; P' U3 |8 C在GNU C 中,用括号将复合语句括起来也形成了表达式。他允许你在一个表达式内使用循环,跳转和局部变量。7 ^1 H3 Q5 }/ X: r7 c% U

) n( q. [+ ~; @, f& \7 v一个复合语句是用大括号{}括起来的一组语句。在包含语句的表达式这种结构中,再用括号( )将大括号括起来,例如:
8 C4 Y; ^  ~  o({ int y = foo (); int z;
+ _. r, G- E& I2 s8 ~  if (y > 0) z = y;
4 [( M, R; q8 p- R) @7 ?4 O  else z = - y;9 J8 j+ X! n: K2 R+ \0 K" }8 o
  z; })# G! O6 \! x6 K# j" w; W1 d
' ?1 {9 D  H7 m
就是一个合法表达式,用于计算foo( )函数返回值的绝对值。
- h) u3 t; G# Z! H1 r2 k7 ^0 r在上面的复合语句中,最后的一句必须是一个以分号结尾的表达式。这个表达式代表了整个结构的值。如果你在大括号里的最后一句用的是其他的语句,则整个结构的返回类型为void,即没有合法的返回值。4 K3 ?4 p7 m+ ~+ W4 P

4 w/ g  b$ ?5 K5 t* H1 [2 m7 o" Y这种特性使得宏定义变得更加安全(因为每个操作数都只被计算一次,例如++运算)。例如计算最大值通常在C语言中被定义为这样的宏: 3 v& Q( \6 W) V/ D1 G
#define max(a,b) ((a) > (b) ? (a) : (b))
5 [* A( b! ?; ~& Y- u
( n) E' ]; f5 A0 V9 {但是其中的a和b可能会被计算两次,如果操作数带有副作用,则会产生错误的结果。在GNU C中,如果你知道了操作数的类型(假设为int),你可以这样安全的定义宏:$ f5 q, F! J/ K$ k  W) Q6 [2 V
#define maxint(a,b) \
2 P$ h" N* `) a({int _a = (a), _b = (b); _a > _b ? _a : _b; })
' |: G8 {' Y5 r7 W" \5 `0 U4 U& L2 Y& ]语句内嵌在常量表达式(例如枚举类型),位域尺寸或静态变量初始化中是不允许的。如果你不知道操作数的类型,你也可以使用typeof来获得类型。8 J# S& I5 d+ y: q6 z& r
语句表达式内嵌在G++中并不支持,而且将来是否支持目前也不清楚(他们在某时被完全支持或者被抛弃掉,或者作为bug会一直存在)。就目前而言,语句内嵌表达式在默认情况下工作的并不好。' M, P2 @% I" \" E2 R- _# T
此外,在C++中语句内嵌表达式还存在很多语义问题。如果你希望在C++中用语句内嵌表达式来代替内联函数(inline function),对象的析构处理可能会让你惊讶。例如:
* Y8 m% N8 g' d#define foo(a) ({int b = (a); b + 3; })0 y# Y6 @1 v" p  C8 A! Y7 G
并不等同于! E3 N5 S6 ?8 A! H
inline int foo(int a) { int b = a; return b + 3; }
. y2 H" p! J1 z) u7 v; Y% C& j具体而言,当传递给foo的表达式的会引入临时对象的生成的时候,这些临时对象的析构在用宏时会早于用函数的情况。
7 I3 P' @+ `7 \& ]; C& _1 {以上情况说明在用于C++代码的.h头文件中使用语句内联表达式并不是一个好主意。一些GNU C的库的某些版本中的使用语句内联表达式的头文件已经造成了这样的bug。

该用户从未签到

2#
发表于 2021-3-11 18:29 | 只看该作者
来学习一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-24 20:33 , Processed in 0.171875 second(s), 24 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表