gcc -ftrapv
gcc に組み込みの「実行時算術オーバーフロー検出」機能 (-ftrapv) について除算に対応していないことを確認した。
$ gcc -ftrapv -x c -S -o - - << EOF > void calc(int a, int b) { > int w = a + b; > int x = a - b; > int y = a * b; > int z = a / b; > } > EOF .file "" .globl __addvsi3 .globl __subvsi3 .globl __mulvsi3 .text .globl calc .type calc, @function calc: pushl %ebp movl %esp, %ebp subl $40, %esp movl 12(%ebp), %eax movl %eax, 4(%esp) movl 8(%ebp), %eax movl %eax, (%esp) call __addvsi3 movl %eax, -16(%ebp) movl 12(%ebp), %eax movl %eax, 4(%esp) movl 8(%ebp), %eax movl %eax, (%esp) call __subvsi3 movl %eax, -12(%ebp) movl 12(%ebp), %eax movl %eax, 4(%esp) movl 8(%ebp), %eax movl %eax, (%esp) call __mulvsi3 movl %eax, -8(%ebp) movl 8(%ebp), %eax cltd idivl 12(%ebp) movl %eax, -4(%ebp) leave ret .size calc, .-calc .ident "GCC: (GNU) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)" .section .note.GNU-stack,"",@progbits
確かに加減乗算は _addvsi3, __subvsi3, __mulvsi3 の組み込み関数呼び出し (call) になっており、除算だけ x86 の idivl (整数除算機械語) になっている。
加減乗算のオーバーフローの発生条件と比較して、除算オーバーフローはほぼ起きない (除数が -1 で被除数が INT_MAX という組み合わせに限る) という実情と、チェックのための関数呼び出しのコストを考えてのことなんだろうな、というメモ。
ありがと > id:yupo5656:20051227:p1