gcc對C語言的擴充套件:語句內嵌表示式(statement-embeddedexpression)
在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會一直存在)。就目前而言,語句內嵌表示式在預設情況下工作的並不好。
一個複合語句是用大括號{}括起來的一組語句。在包含語句的表示式這種結構中,再用括號( )將大括號括起來,例如:
({ 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。
本文轉自nathanxu 51CTO部落格,原文連結:http://blog.51cto.com/nathanxu/6027,如需轉載請自行聯絡原作者
相關文章
- C++對C語言的擴充套件(1)--引用C++C語言套件
- C++學習筆記-C++對C語言的函式擴充C++筆記C語言函式
- 擴充套件表示式套件
- c語言是如何解析表示式語句"2+3*4;"的?C語言
- Cython,一個簡化 Python 編寫 C 擴充套件的語言Python套件
- c 語言除錯方法(除錯 PHP 底層、擴充套件)除錯PHP套件
- 09. C語言內嵌彙編程式碼C語言
- 表示式與語句
- C語言-GCC的簡單介紹C語言GC
- C++ 對C的擴充套件有哪些C++套件
- Cilium 1.3:支援Envoy、Cassandra和Memcached的Go語言擴充套件Go套件
- Python中表示式與語句Python
- 表示式和基本語句的規範
- JSP 表示式語言概述JS
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- 淺談Kotlin語法篇之擴充套件函式(五)Kotlin套件函式
- 程式語言中表示式更優於語句
- C語言與嵌入式C語言的區別C語言
- Zoey.Dapper–Dapper擴充套件之把SQL語句放到檔案中APP套件SQL
- Linguistics-English-區分 that Vs. which + 定語(refine限定主句)從句 Vs. 同位語(expand擴充套件補充主句)從句NGUI套件
- C語言的函式C語言函式
- ACM – 第四章 gcc,函式,堆疊,以及C語言ACMGC函式C語言
- 【Kotlin】擴充套件屬性、擴充套件函式Kotlin套件函式
- soar-PHP - SQL 語句優化器和重寫器的 PHP 擴充套件包、 方便框架中 SQL 語句調優PHPSQL優化套件框架
- 算數表示式求值--c語言課程設計C語言
- Notepad++編譯和執行C語言 (GCC)編譯C語言GC
- vue3 setup語法糖 擴充套件Vue套件
- 語句和表示式有什麼不同
- realloc 實現隨使用者輸入自動擴充套件陣列長度(C語言)套件陣列C語言
- laravel-soar - 在 Laravel 中輕鬆容易的優化 sql 語句的擴充套件包Laravel優化SQL套件
- c語言if語句是如何變成彙編程式碼的?C語言
- 使用Kotlin擴充套件函式擴充套件Spring Data案例Kotlin套件函式Spring
- C語言常用函式C語言函式
- C語言 execve()函式C語言函式
- Shell—擴充套件正規表示式(awk、sort、uniq、tr工具)套件
- nginx配置檔案語法高亮的Sublime Text擴充套件Nginx套件
- SG :一個簡單的PHP語法糖擴充套件PHP套件
- 更好用、能擴充套件、支援多國語言提示的表單驗證類庫套件
- C語言函式sscanf()的用法C語言函式