許多開發者對 C 語言中 const 的行為存在誤解。透過一道經典面試題,我們來深入剖析 const 的真實運作機制。
const int a = 1;
int *b = (int *)&a;
*b = 31;
結果:程式碼可編譯通過、成功執行,且 a 與 b 的值均為 31。
C 語言的 const 主要是一個編譯期的語法限制,而非執行期的記憶體保護機制:
const 變數,若有則報錯(如 a = 2; 會觸發 error C2166)const 變數與普通變數在記憶體中無差異,皆可透過指標間接修改早期 C 標準(C89/C90)原本沒有 const,此關鍵字是從 C++ 引入 C 標準的。C 編譯器對 const 的處理相對簡單:
const 變數與普通變數在機器碼層面完全一致// 直接修改 - 編譯錯誤
const int a = 1;
a = 2; // error C2166: l-value specifies const object
// 間接修改 - 編譯通過、執行正常
const int a = 1;
int *b = (int *)&a;
*b = 31; // a 變為 31
// 甚至 memset 也能修改
memset(&a, 0xFF, sizeof(int)); // 無錯誤
const 在 C 中本質上是「編譯器承諾」:
「我承諾不會在原始碼中直接修改這個變數」,而非「這塊記憶體不可寫入」。
這也是為何透過指標繞過編譯器檢查即可修改的根本原因。開發者應將 const 視為代碼可讀性與維護性的工具,而非安全機制。