三項演算子

円舞君が最近Cを勉強してるらしい。で、3つの値の最大値を返す関数*1はこんな感じかと聞いてきた

int max(int a,int b,int c){
  if(a>b){
    if(a>c){
      return a;
    }else{
      return c;
    }
  }else if(b>c){
    return b;
  }else{
    return c;
  }
}

ので1行で書いてみた。

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

じゃあ実際どれくらい違うのかと思ったのでgcc -Sでアセンブリコードを見てみた。

.globl _ifmax
  .def  _ifmax; .scl  2; .type  32; .endef
_ifmax:
  pushl  %ebp
  movl  %esp, %ebp
  subl  $4, %esp
  movl  8(%ebp), %eax
  cmpl  12(%ebp), %eax
  jle L2
  movl  8(%ebp), %eax
  cmpl  16(%ebp), %eax
  jle L3
  movl  8(%ebp), %eax
  movl  %eax, -4(%ebp)
  jmp L1
L3:
  movl  16(%ebp), %eax
  movl  %eax, -4(%ebp)
  jmp L1
L2:
  movl  12(%ebp), %eax
  cmpl  16(%ebp), %eax
  jle L6
  movl  12(%ebp), %eax
  movl  %eax, -4(%ebp)
  jmp L1
L6:
  movl  16(%ebp), %eax
  movl  %eax, -4(%ebp)
L1:
  movl  -4(%ebp), %eax
  leave
  ret

.globl _sanmax
  .def  _sanmax;  .scl  2; .type  32; .endef
_sanmax:
  pushl  %ebp
  movl  %esp, %ebp
  subl  $12, %esp
  movl  8(%ebp), %eax
  cmpl  12(%ebp), %eax
  jle L9
  movl  8(%ebp), %eax
  movl  %eax, -8(%ebp)
  movl  16(%ebp), %eax
  movl  %eax, -4(%ebp)
  movl  -8(%ebp), %eax
  cmpl  %eax, -4(%ebp)
  jge L10
  movl  -8(%ebp), %eax
  movl  %eax, -4(%ebp)
  jmp L10
L9:
  movl  12(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  16(%ebp), %eax
  movl  %eax, -4(%ebp)
  movl  -12(%ebp), %eax
  cmpl  %eax, -4(%ebp)
  jge L10
  movl  -12(%ebp), %eax
  movl  %eax, -4(%ebp)
L10:
  movl  -4(%ebp), %eax
  leave
  ret

おお、どっちも同じ行数だ。-Oとかやると両方とも分量は減るが、最適化のレベルを上げてみても全く同じになるわけでもないらしい。

ランキング→   

*1:実際はもうちょっと複雑