編譯器

在上方程式碼中,將 sq 行內展開之後接著生效的最佳化,以及其結果,下列何者正確?

static int sq(int v) { return v * v; }
int g(void) { return sq(6) + 1; }
  1. A藉由共同子運算式消除,g 會變成呼叫 sq 兩次
  2. B藉由常數摺疊,g 會變成只回傳 37 的程式碼
  3. C藉由迴圈展開,v * v 被替換為6次加法
查看答案與解析

正確答案:B. 藉由常數摺疊,g 會變成只回傳 37 的程式碼

將 sq 行內展開後,g 的內容會變成 return 6 * 6 + 1;,乘法的運算元全部成為常數。接著進行常數摺疊,就能算出 6 * 6 = 36、36 + 1 = 37,g 就變成只回傳37的程式碼。行內展開不僅能消除呼叫的開銷,也能像這樣使運用呼叫端的值的最佳化成為可能,這是它的一大優點。這裡沒有迴圈,也不會變成呼叫 sq 兩次。

  • A. 呼叫反而會消失。
  • B. 正確。展開後常數摺疊生效,只剩下37。
  • C. 這段程式碼中沒有迴圈。
練習這個領域 前往領域頁面

編譯器的其他題目

  1. 關於軟體管線化(software pipelining)的說明,下列何者正確?
  2. 在嚴格的設定下,編譯器不會擅自將浮點數的加法 (a + b) + c 重新排列為 a + (b + c),其理由下列何者正確?
  3. 編譯器的自動向量化所使用的指令種類,下列何者正確?
  4. 編譯器的最佳化必須遵守的基本條件,下列何者正確?
  5. 關於程式碼產生階段之一的指令選擇(instruction selection)的說明,下列何者正確?

這個領域的比較