C言語のトライ&エラーに最適なrungcc

最近LLを使っているせいで、irb,gosh,ghci,perlsh・・・そしてrlwrapにお世話になっている。
何が便利かって?関数の挙動忘れてたり、言語の構文忘れてたりしたときのトライ&エラーが出来る点だ。
そこでGaucheCGIラッパー作る際にお世話になったのがrungccというgccラッパー。

引数を実行
$ rungcc -e 'main(){puts("hello");}'

mainを書くのをさぼる場合
$ rungcc -m 'puts("hello")'

返値を整数として表示
$ rungcc -d '1+1'
2

返値を浮動小数として表示
$ rungcc -f '1.0/3.0'
0.333333

例えば、コマンドライン引数の扱い方忘れたなぁと思ったあなた!

$ rungcc -s '*(argv+1)' arg1 arg2 arg3
arg1
$ rungcc -s '*(argv+2)' arg1 arg2 arg3
arg2
$ rungcc -s '(argv+2)[0]' arg1 arg2 arg3
arg2
$ rungcc -s 'argv[2]' arg1 arg2 arg3
arg2

このとおり、最小限の記述であなたにコマンドライン引数の出し方とポインタの懐かしさを思い出させてくれます。

また、execの引数どうあつかうんだっけ?

$ rungcc -m 'execv(argv[1],argv+1);' /bin/ls -al
合計 178
(事情により中略(笑))
$ rungcc -m 'execv(argv[1],argv+1);' /bin/ls
Maildir  bin  public_html  ruby (事情により中略(笑))

の用に見事な確認作業が行えます。

うん十年前と違って、Cのコンパイルがあまりにも速い為あたかもLLのように思えてきます。
しかも忘れがちなinclude,main()等を省くことが出来ます。*1

そしてCの文字列の扱いの厳しさというか標準の演算子から取り残されたセコさをかみしめることが出来ます。*2

$ rungcc -s 'strcat("abc","def")'
$ rungcc -s '(char s[10];strcat(s,"abc"))'
<stdin>: In function 'main':
<stdin>:5: error: expected ')' before 's'
<stdin>:5: error: expected expression before ')' token
$ rungcc -m 'char s[10];strcat(s,"abc");printf("%s\n",s);'
abc
$ rungcc -m 'char s[10];strcat(s,"abc");strcat(s,"def");printf("%s\n",s);'
abcdef

ほら、君もこれで立派にCを思い出せます。*3

時間もほら10倍程度の差、0.1秒以内なので体感スピードはかわらない。

$ time rungcc -m 'char s[10];strcat(s,"abc");strcat(s,"def");printf("%s\n",s);'
abcdef

real    0m0.095s
user    0m0.080s
sys     0m0.010s
$ time ruby -e 'puts "abc"+"def"'
abcdef

real    0m0.007s
user    0m0.000s
sys     0m0.000s
$

*1:私は一度mainを完全に忘れて困ったことがあります。

*2:String型があるだけでもjavaってすごいと少し思ったけど、String型が他のオブジェクトと扱いが違うところがjavaの悪いところ。

*3:文字列+漢字コードで苦しんでコンパイル待ちした。あの甘酸っぱい記憶が(笑)