宣言その2
kinaba さんの tweet から。
Cの型宣言、年に一回くらい流行る「英語で読む」という方法が、簡単なものをわざと難しく見せているように思えて好きになれないのです。(その方針の是非はさておき)使う時の構文と宣言の構文が似るようにという方針で設計されてるのだからそう読んだ方が素直では。
別の言い方をすると、"a ptr to func returning ptr to func returning char" だと判明して何か嬉しいでしょうか。それは一体なんなのか。それは「デリファレンスして0引数適用してデリファレンスしてint適用したらcharになる物体」(続
続) ですし、それは char (*(*fp)(void))(int); という宣言にまさにその通りのことが書いてある。
なるほど。const/volatile は置いておいて、英語にしたところで微妙なのはそのとおりな気がする。
じゃ、ま、S式にしてみる。
void (*signal(int, void (*)(int)))(int)
(declare :identifier 'signal :type (function :return (pointer (function :return 'void :args '(int))) :args (list 'int (pointer (function :return 'void :args '(int))))))
double (*(*(*f)(double))(double))(double)
(declare :identifier f :type (function :return (pointer (function :return (pointer (function :return 'double :args '(double))) :args '(double))) :args '(double)))
あぁ、うん。どうだろね。
宣言
まぁ、普通は typedef 使え、ってな話だよね。signal の宣言なんか typedef 使わないとひどい。
/* with typedef */ typedef void (*sighandler_t)(int); signalder_t signal(int signo, sighandler_t handler); /* without typedef */ void (*signal(int signo, void (*handler)(int)))(int);
ちなみに、宣言文と英語を相互変換してくれる Web サイトとかあったりする(ただし、仮引数の名前は書けない)。
- ref:http://cdecl.org
変換プログラム自体も公開されている。
% wget http://cdecl.org/files/cdecl-blocks-2.5.tar.gz % tar zxf cdecl-blocks-2.5.tar.gz % make yacc cdgram.y && mv y.tab.c cdgram.c lex cdlex.l && mv lex.yy.c cdlex.c gcc -g -O2 -o c++decl cdecl.c rm -f cdecl ln -s c++decl cdecl % ./cdecl Type `help' or `?' for help cdecl> explain void (*signal(int, void (*)(int)))(int) declare signal as function (int, pointer to function (int) returning void) returning pointer to function (int) returning void cdecl> exit
あと、C++ だとメンバへのポインタもあるのでさらにややこしいとか、const/volatile もあるよ、とかいう話も。
% ./c++decl Type `help' or `?' for help c++decl> explain int X::*x declare x as pointer to member of class X int c++decl> explain int (X::*x)(int) declare x as pointer to member of class X function (int) returning int c++decl> explain const int *p declare p as pointer to const int c++decl> explain int * const p declare p as const pointer to int c++decl> exit
追記1
sighandler_t の宣言を間違えていたので修正。
underscore
それ、アンダースコア・・・
shared object 中のグローバル変数を出力する
shared object 中のグローバル変数の中身をそれなりの見た目にして出力するツールなど。まぁ、なんか shinh さんの dumper が元ネタなわけですが。
DWARF を読んで、型情報を読んでいるので、-g とか -gdwarf-2 とかつけてコンパイルする必要あり。あと、libelf と libdwarf が必要。Debian 系だと libelf-dev, libdwarf-dev かな。RedHat 系はよくわからんですが。
久しぶりに C++ などで書いて思ったこと。
- メソッドのパラメータを変更すると宣言と実装の両方編集する必要あってめんどい。
- Google では例外禁止とか聞いた気がしたので例外なしでやってみたら一々返り値のチェックが必要でめんどい。
- そもそもエラー処理がめんどい。めんどいので assert でお茶を濁す。
やりたいこととか
- *.o の読み込み。なんかちゃんと libelf つかえばいけそう
できてないこと
- 関数ポインタ
- 列挙型。まぁ、普通にやれば出来そう。
そもそもこんなの欲しい人いるのかという話なんだが。
カラー表示
ふと思った疑問。Emacs カラー表示っていつぐらいからできるようになったんでしょ? キーワードの色つけ表示が入った頃? 最初に実装したエディターは?
そいや、昔、Vine の Emacs には、color-mate なんてのが入っていたな、と思って color-mate 7.10 のパッケージの中身を見てみた。
ウィンドウシステムにあまり対応していない バージョン 1 の mule や
バージョン 18 の emacs にも対応していて、できる限りカラー化します。その時
には、 mule / emacs が ウィンドウシステムに対応している必要があります。
カラーにならない時はこれが原因と考えられます。なるべく バージョン 2 の mule や バージョン 19 の emacs を使用して下さい。
そのほうがより派手にカラー化できます。
とりあえず、emacs 18 ではカラー表示ができたようだ。