語句內(nèi)嵌表達式格式為({xxx});其返回值為最后一個表達式的值
花括號內(nèi)可以是各種表達式,但是最后一個表達式必須是非聲明以分號結尾的表達式,比如:最后如果是int test = 5;就會報錯, int test = 5并沒有返回值。
語句內(nèi)嵌表達式最常用的地方是在宏定義中。
1.比如常用的max定義
如果普通定義#define max(a,b) ((a) > (b) ? (a) : (b)),那么ab有一個會被計算了兩次,結果就錯了
假如int a = 2, b = 3;
mac(a++,b++)展開后為
((a++) > (b++) ? (a++) : (b++)) = 5那么就錯了,應該返回4才對;
如果使用內(nèi)嵌表達式:#define maxint(a,b)
({int _a = (a), _b = (b); _a > _b ? _a : _b; })則只會計算一次就不會錯了。
2.比如#define RACObserve(TARGET, KEYPATH) \
({ \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored "-Wreceiver-is-weak"") \
_weak id target = (TARGET); \
[target_ rac_valuesForKeyPath:@keypath(TARGET, KEYPATH) observer:self]; \
_Pragma("clang diagnostic pop") \
})
也是利用內(nèi)嵌表達式,前面式子作處理,返回最后一個式子的值實現(xiàn)的
3.在iOS上自己diy一個更高效的宏
iOS上一般判斷版本是否大于都用#define SYSTEM_VERSION_IS_IOS11OR_ABOVE ([[[UIDevice currentDevice] systemVersion] compare:@"11" options:NSNumericSearch] != NSOrderedAscending)
這個語句里相對來說[[UIDevice currentDevice] systemVersion] 是比較慢的,而compare也不是那么快,系統(tǒng)提供的if (@available(iOS xx, *))已經(jīng)優(yōu)化到讀取BOOL變量的速度級別,但是有一點比較坑,作為condition的時候不能再作"與"或者"或"的運算,而我們使用內(nèi)嵌表達式就可以實現(xiàn)既高效,又可以和其他BOOL作運算的宏
#define E_SYSTEM_VERSION_IS_IOS11OR_ABOVE \
({ \
BOOL tmp = NO;\
if (@available(iOS 11.0, *)) tmp = YES;\
tmp;\
})
經(jīng)測試SYSTEM_VERSION_IS_IOS11OR_ABOVE的耗時是E_SYSTEM_VERSION_IS_IOS11OR_ABOVE的五六百倍,其中[[UIDevice currentDevice] systemVersion] 多耗時500倍,compare多耗時幾十倍
但是g++不支持,使用時也要注意。