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,如需轉載請自行聯絡原作者
相關文章
- gcc對C語言的擴充套件:語句內嵌表示式(statement-embedded expression)薦GCC語言套件Express
- C++對C語言的擴充套件(1)--引用C++C語言套件
- 對《gcc中的內嵌組合語言》一文的補充說明GC組合語言
- 用C語言擴充套件Python的功能C語言套件Python
- C++11語言擴充套件:常規特性C++套件
- 擴充套件表示式套件
- C++學習筆記-C++對C語言的函式擴充C++筆記C語言函式
- c語言是如何解析表示式語句"2+3*4;"的?C語言
- c 語言除錯方法(除錯 PHP 底層、擴充套件)除錯PHP套件
- 09. C語言內嵌彙編程式碼C語言
- C++的那些事:表示式與語句C++
- XBRL(可擴充套件商業報告語言套件
- Go 語言編寫 CPython 擴充套件 goPyGoPython套件
- YCSB擴充套件-語句執行頻率,執行指定的測試查詢語句套件
- Cython,一個簡化 Python 編寫 C 擴充套件的語言Python套件
- Swift 小貼士:語言的擴充套件和自定義Swift套件
- C++ 對C的擴充套件有哪些C++套件
- C語言-GCC的簡單介紹C語言GC
- Cilium 1.3:支援Envoy、Cassandra和Memcached的Go語言擴充套件Go套件
- gcc核心擴充套件linuxforum(轉)GC套件Linux
- 可擴充套件客戶資訊語言 (xCIL) 簡介 (轉)套件
- 一步步來用C語言來寫python擴充套件C語言Python套件
- C#3.0之神奇的Lambda表示式和Lambda語句C#
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- iOS擴充-語言國際化iOS
- C語言函式手冊:c語言庫函式大全|C語言標準函式庫|c語言常用函式查詢C語言函式
- 程式語言中表示式更優於語句
- C語言與嵌入式C語言的區別C語言
- C語言goto語句以及用goto語句構成迴圈C語言Go
- Apache模組開發/用C語言擴充套件apache(3:一個非常簡單的apache module)ApacheC語言套件
- Python中表示式與語句Python
- SQL語句與正規表示式SQL
- 淺談Kotlin語法篇之擴充套件函式(五)Kotlin套件函式
- C語言的本質(32)——C語言與彙編之C語言內聯彙編C語言
- C語言的函式C語言函式
- 語音合成在語音助手中的應用及擴充套件套件
- JSP 表示式語言概述JS
- JSP表示式語言(EL)JS