GNU C 允許用括號包裹複合語句形成表達式:
({ int y = foo(); int z;
if (y > 0) z = y;
else z = -y;
z; })
大括號內最後一句必須是**以分號結尾的表達式**,其值為整個結構的值。若最後非表達式,則型別為 void 無返回值。
傳統宏定義最大值:
#define max(a,b) ((a) > (b) ? (a) : (b))
若引數有副作用(如 max(i++, j++)),i++ 可能被求值兩次導致錯誤。GNU C 可用語句表達式安全定義:
#define maxint(a,b) \
({ int _a = (a), _b = (b); _a > _b ? _a : _b; })
引數只被求值一次,存入區域變數再比較。若型別未知,可搭配 typeof 進一步泛化。
inline 函式,臨時物件析構時機不同。例:#define foo(a) ({int b = (a); b + 3;})
// vs
inline int foo(int a) { int b = a; return b + 3; }
傳遞產生臨時物件的表達式時,宏版本析構較早,可能導致資源管理錯誤。因此 .h 頭文件中避免使用語句表達式,部分 GNU C 庫舊版因濫用此特性已引發 bug。
語句內嵌表達式是 GNU C 強大擴展,能寫出更安全的宏,但**僅限 C 程式碼**,C++ 項目慎用,且受限於常量表達式等場合。理解其機制有助於閱讀開源專案代碼。