#include
#include
void main() {
char buf[256];
int *x = (int*)&buf[1]; // 奇數地址
*x = 68000; // Bus Error (SPARC/RISC)
printf("*x = %d\n", *x);
}
在 SPARC 等 RISC CPU 上運行會觸發 Bus error (core dumped);而在 x86 (Pentium) 上正常運行。
int (4 字節) 必須存放在 4 的整數倍地址(0, 4, 8...)。buf 數組大小 256 (4 的倍數),編譯器將其起始地址對齊到 4 的倍數(如 0x1000)。&buf[1] 地址為 0x1001,非 4 的倍數。(int*) 並解引用寫入,CPU 檢測到地址未對齊 → 觸發總線錯誤中斷。char 只有 8bit,怎麼轉成 32bit 的 int*?&buf[1] 是地址,轉型後告訴編譯器「這地址存放 int」,實際內存位模式不變。buf 從 0x1000 開始:&buf[1] = 0x1001(int*)0x1001 類型轉換*x = 68000 向 0x1001~0x1004 寫入 4 字節union { char buf[256]; int i; } u; 保證 u.i 對齊。int val = 68000; memcpy(&buf[1], &val, sizeof(int)); 部分架構允許非對齊 memcpy。__attribute__((packed, aligned(1))) 強制取消對齊(慎用,性能損失)。val = buf[0]<<24 | buf[1]<<16 | ...)或 memcpy 到對齊變量。-Wcast-align 檢測潛在非對齊轉型。Bus Error 本質是硬件對內存訪問對齊的強制檢查。RISC 選擇「簡化硬件、編譯器負責對齊」,x86 選擇「硬件兼容、性能妥協」。理解這一差異,編寫可移植、高性能的系統級代碼時,務必遵循「嚴格對齊」原則,必要時用 memcpy 或聯合體規避風險。