編譯器
在上方函式中,編譯器無法直接進行把 *b 的讀取移到迴圈之外的最佳化,其原因為何?
void add(int *a, int *b, int n) {
for (int i = 0; i < n; i++)
a[i] += *b;
}
- A因為 *b 是整數,移到迴圈外會使值的精確度下降
- B因為 a 與 b 可能指向同一個位置,對 a[i] 的寫入可能會使 *b 改變
- C因為規定編譯器絕對不可以最佳化以指標為引數的函式
查看答案與解析
正確答案:B. 因為 a 與 b 可能指向同一個位置,對 a[i] 的寫入可能會使 *b 改變
乍看之下,*b 在迴圈中不會改變,似乎只讀一次就好。然而若呼叫端像 add(x, &x[3], n) 這樣,傳入指向 a 的某個元素的指標作為 b,對 a[3] 的寫入就會使 *b 的值改變。編譯器無法否定這種可能性(別名),所以會產生每次都重新讀取的程式碼。在C語言中,若對指標加上 restrict,保證它們指向不同的位置,就能進行最佳化。這既不是精確度的問題,也不是最佳化遭到禁止。
- A. 移動整數的讀取並不會改變精確度。
- B. 正確。因為 a 與 b 有重疊的可能(別名)。
- C. 使用指標的函式同樣可以被最佳化。