現代 C (C11/C17/C23)

alignas 與 alignof(對齊指定與查詢)

/ a-LINE-az, a-LINE-of /

硬體不會把資料隨意擺放:4 位元組的 int 通常要落在 4 的倍數位址,8 位元組的 double 要落在 8 的倍數位址。這項需求稱為對齊(alignment),位址是 N 的倍數就稱為 N 對齊。多數時候編譯器會幫你安排好,但有時你需要「查詢」某型別的對齊,或「要求」比平常更強的對齊。

alignof(T) 是編譯期運算子,以 size_t 給出型別 T 的對齊需求(例如 alignof(double) 常為 8)。alignas(N) 是你附加在宣告上的指定子,強制至少 N 位元組對齊,其中 N 是 2 的次方——例如 alignas(64) double buf[8] 會把 buf 放在 64 位元組邊界上。底線拼法 _Alignof 與 _Alignas 是 C11 關鍵字;無前綴的 alignof 與 alignas 在 C11 是 <stdalign.h> 的巨集,到 C23 變成真正的關鍵字。要求比型別自然需求「更小」的對齊是不允許的。

它們對效能與正確性都重要:把常用的緩衝區對齊到 64 位元組的快取行(cache line)可避免執行緒間的偽共享(false sharing),而某些 SIMD 與 DMA 硬體要求特定對齊,否則會發生錯誤。一個常見誤解:對齊談的是「位址」而非「大小」——某型別可能是 12 位元組卻只需 4 位元組對齊,而結構內的填充(padding)存在的目的正是讓每個成員都正確對齊。

#include <stdalign.h> alignas(64) double buf[8]; // 讓 buf 起始於 64 位元組(快取行)邊界 size_t a = alignof(double); // 通常是 8 // (uintptr_t)buf % 64 == 0

alignof 讀取型別的自然對齊;alignas 把宣告的對齊提高到所選的 2 的次方。

對齊談的是位址為 N 的倍數,而非大小;你可以用 alignas 加強對齊,但絕不能把型別弱化到低於它的自然需求。

又稱
_Alignas_Alignofalignment specifier對齊指定子