const char i = 1;
char *j = (char *)&i;
*j = 2; // 透過指標修改
printf("%d, %d\n", i, *j); // 輸出: 1, 2
現象:i 在記憶體中確實被改為 2,但 printf 輸出 i 卻仍為 1。
原因:編譯器見 const,優化時直接將 i 的值 (1) 嵌入指令碼,而非從記憶體讀取。組合語言中:mov eax, 1 而非 mov eax, [i]。
解決:加 volatile 強制編譯器每次從記憶體讀取:volatile const char i = 1;。
告訴編譯器:此變數可能被「意想不到」地改變 (硬體、中斷、多執行緒),禁用快取優化,每次存取必須讀寫記憶體。
int square(volatile int *ptr) {
return (*ptr) * (*ptr); // 錯誤:ptr 可能在兩次讀取間被改變
}
正確寫法:
long square(volatile int *ptr) {
int val = *ptr; // 只讀一次
return (long)val * val;
}
const:語意承諾「不修改」,編譯器可優化。volatile:語意警告「可能外部修改」,禁用優化。