gcc さんのよくわからない挙動
builtin 関数
golf のときは普通 #include せずに書くわけだけど,引数として関数を渡そうとすると undeclared と言われてしまう.
…なんかうまく説明できないので例で示すと,
main(){printf("hello\n");}
のように,関数を呼び出す形で使用する場合は imcompatible implicit declaration of built-in function ' printf' という warning は出るけどコンパルはできる.
一方,
main(){printf("%p\n",puts);}
のように,builtin 関数を引数として渡そうとすると ' puts' undeclared という error が出てコンパイルできない.
まぁ
main(){printf("%p\n",__builtin_puts);}
として明示的に builtin 関数を使用したり,
main(){printf("%p\n",printf);}
のように,それより前に使った関数ならコンパイル通る模様.
関数呼び出しが消される
f(s){strcmp(s,"t");}main(){printf("%d\n",f("s"));}
_f: 00001fbe pushl %ebp 00001fbf movl %esp,%ebp 00001fc1 subl $0x08,%esp 00001fc4 leave 00001fc5 ret
となっていて,見事に strcmp が無かったことになっている.
最適化を無くした状態でこれってどうなんだろう…
見つけた解決法としては,
f(s){-strcmp(s,"t");}
とすると,
_f: 00001f9a pushl %ebp 00001f9b movl %esp,%ebp 00001f9d pushl %ebx 00001f9e subl $0x14,%esp 00001fa1 calll 0x00001fa6 00001fa6 popl %ebx 00001fa7 leal 0x0000004f(%ebx),%eax 00001fad movl %eax,0x04(%esp) 00001fb1 movl 0x08(%ebp),%eax 00001fb4 movl %eax,(%esp) 00001fb7 calll 0x0000300a ; symbol stub for: _strcmp 00001fbc addl $0x14,%esp 00001fbf popl %ebx 00001fc0 leave 00001fc1 ret
となって,strcmp がちゃんと呼ばれるようになった.
C のコードを見ると符号が反転されてしまうように見えるが,アセンブリを見ての通り何故かそんなことはない.
なんでこうなるんだろう.すごい不思議だけど,gcc のソースを見る勇気と根気は無い…