const int n = 10;
int *p = (int *)&n;
*p = 20;
printf("%d\n", n); // 輸出 20 (GCC/Clang -O0),或 10 (優化後)
const int n:告訴編譯器「我不會直接修改 n」,編譯器可將其放入唯讀段,並對直接存取 n 的代碼進行常數傳播優化(直接嵌入 10)。(int *)&n:強制類型轉換移除 const 資格,取得可寫指針。*p = 20:透過指針寫入記憶體。若 n 在唯讀段 → 段錯誤;若在資料段 (未優化/嵌入式) → 修改成功。printf("%d", n):若編譯器已常數傳播,印 10;若未優化,讀記憶體印 20。行為未定義。C 標準 (ISO/IEC 9899) 明確指出:嘗試修改 const 限定的物件屬於未定義行為 (UB)。編譯器不保證任何結果。
n = 20,編譯器報錯。const int *p 承諾「透過 p 不修改指向物件」,但物件本身可能非 const。void func(const int *ptr) { /* 只讀 ptr */ }
int main() {
int a = 10; func(&a); // 非 const 物件傳給 const 指針:合法
const int b = 20; func(&b); // const 物件傳給 const 指針:合法
// int *p = &b; // 錯誤:const 物件不可轉非 const 指針 (需強轉,但極度危險)
}
const 是給編譯器和維護者看的「承諾」,不是給硬體看的「鎖」。絕不透過強轉修改 const 物件,否則觸發 UB,導致程式在不同優化等級/平台表現不一。