現代 C (C11/C17/C23)
複合常值(compound literal)
/ KOM-pound /
有時你想在使用處就地建立一個臨時的結構或陣列,而不必先為它宣告一個具名變數。複合常值正是如此:你以括號包住一個型別、後接大括號初始化子,就地造出一個無名物件,例如 (struct point){ .x = 3, .y = 4 }。它給你一個現成的物件,可立刻傳給函式或取其位址。
形式是 (型別){ 初始化列 },大括號接受與一般宣告相同的指定初始化子語法。結果是一個真正的左值(lvalue)——它有位址,所以 &(int){5} 是指向持有 5 的 int 的合法指標。它的生存期取決於出現的位置:寫在函式內的複合常值具有「自動」儲存期,表示它只活到所在區塊結束,就像區域變數;寫在檔案範圍的則具有靜態儲存期。這個特性出自 C99。
它對寫出精簡程式碼很有用:把臨時的設定結構傳給函式、就地建構陣列引數、或讓指標指向一個小型固定物件。關鍵提醒:因為區塊範圍的複合常值在其區塊結束時消亡,若你回傳或儲存指向它的指標以供日後使用,就會得到「懸置指標」與未定義行為——它的生命期是該區塊,而非整個程式。
void draw(struct point p); draw((struct point){ .x = 3, .y = 4 }); // 臨時物件,無具名變數 int *q = &(int){ 42 }; // 指向就地 int 的指標 // 在此區塊內可用;區塊結束後 q 就懸置了
一個就地的無名物件,具有真實位址;在函式內它只活到所在區塊結束。
區塊範圍的複合常值具有自動儲存期:在其區塊結束後仍保留指向它的指標,就是懸置指標與未定義行為。
又稱
另見