ゆとりーなの日記

日記的な事を書いて行くと思はれる

コンパイラVS人間

普通にネタがあったのを思い出しました。

inlineは忘れられた子

今時のコンパイラはinlineを無視するという噂が流れていますが、せっかくアセンブラを勉強したことですし、調べてみようじゃありませんか。

先ずは恒例のinlineの仕様

宣言はこうですね。関数の返り値型の前にinlineと書くだけです。

inline int max(int a, int b) {
  return a > b ? a : b;
}

上の例ではマクロ的な使い方が出来ます。inline指定された関数を呼び出すと中身が展開されるので関数呼び出しのオーバーヘッドが消えます。これにより速くなると言われています。
因みに以下の様に関数の定義が呼び出し部から見えないとインライン展開は無視される処理系が多いらしいです。

// インライン展開されないことが多い例

inline int max(int a, int b);

int main() {
  printf("%d", max(10, 20));
  return 0;
}

inline int max(int a, int b) {
  return a > b ? a : b;
}
早速アセンブル

実験コンパイラにはVC++2008EEを使うことにしました。まあ何だかんだ言っても定番コンパイラですし、オプションでアセンブラ吐いてくれるのが美味しいです。因みに全てReleaseビルドです。
検証コードです。

inline int max(int a, int b) {
  return a > b ? a : b;
}

int main() {
  int a(max(10, 20));
  return a;
}

これ位単純だとアセンブラも見やすいですね。
main関数の中身を見ると、

mov eax, 20
ret 0

定数直打ちです。インライン展開されている空気が漂ってますね。
続いてinlineを取ってみます。

int max(int a, int b) {
  return a > b ? a : b;
}

int main() {
  int a(max(10, 20));
  return a;
}

アセンブラです。

mov eax, 20
ret 0

関数呼び出しはありません。というか変わってません。恐るべき最適化。inlineを付けなくてもコンパイラが勝手に最適化してくれることが判明しました。多分。