現代 C (C11/C17/C23)

typeof / typeof_unqual(型別查詢運算子)

/ TIPE-of /

有時你想宣告一個新變數,型別與某個既有運算式「完全相同」,又不必把型別名稱寫出來——這在你不知道呼叫者型別的巨集中很方便。typeof 運算子長期是 GNU 擴充,在 C23 標準化,它給你某運算式(或某型別)的型別,你接著可在任何允許型別名稱之處使用它。

typeof(expr) 給出 expr 的型別,typeof(T) 給出 T 本身。所以 typeof(x) y; 宣告 y 與 x 同型別,typeof(int *) p; 宣告 p 為 int *。與 sizeof 一樣,當運算元只是運算式時,typeof「不會」求值它(只檢查型別),所以沒有副作用。C23 還加入 typeof_unqual,它給出相同型別但「去除」頂層的 const、volatile 等限定詞——當你想要一個全新、可寫副本的型別而非唯讀型別時很有用。例如若 x 是 const int,typeof(x) 是 const int,而 typeof_unqual(x) 是純 int。

它在「必須適用於任何引數型別」的巨集中最有用:一個安全的 MAX 巨集可以把引數存進它們各自型別的暫存變數,以便每個只求值一次,這就用 typeof 寫成。提醒:typeof 精確擷取靜態型別,包含限定詞與陣列性,這很強大,但也意味著你有時會特意想用 typeof_unqual 去掉一個不想帶著走的 const。

#define MAX(a, b) ({ typeof(a) _x = (a); typeof(b) _y = (b); \ _x > _y ? _x : _y; }) const int c = 5; typeof(c) d = c; // d 是 const int typeof_unqual(c) e = c; // e 是純 int(去掉 const)

typeof 把運算式的精確型別複製到新宣告;typeof_unqual 相同,但去掉頂層的 const/volatile。

typeof 連限定詞也擷取,所以 typeof(const int) 會保留 const;當你想要型別的未限定、可寫副本時,請改用 typeof_unqual。

又称
typeof operatortype inference operator型別擷取運算子