宣言
まぁ、普通は 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 ではカラー表示ができたようだ。
ローマ数字変換
えーと、じゃ、Scala で。
assert はテストとは違う気がするが、まぁいいか。
object RomanNumber { val romanDigits = List( ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400), ("C", 100), ("XC", 90), ("L", 50), ("XL", 40), ("X", 10), ("IX", 9), ("V", 5), ("IV", 4), ("I", 1) ) def parse(s: String): Int = { def parseImpl(s: String, digits: List[(String, Int)], result: Int) : Int = if (s.length == 0) result else if (digits.isEmpty) throw new IllegalArgumentException() else if (s.startsWith(digits.head._1)) parseImpl(s.substring(digits.head._1.length), digits, result + digits.head._2) else parseImpl(s, digits.tail, result) parseImpl(s.toUpperCase, romanDigits, 0) } def format(n: Int): String = { if (n < 1 || n > 3999) throw new IllegalArgumentException() def formatImpl(n: Int, digits: List[(String, Int)]): List[String] = if (n == 0) List() else if (n >= digits.head._2) digits.head._1 :: formatImpl(n - digits.head._2, digits) else formatImpl(n, digits.tail) def join(xs: List[Object]) = { val builder = new StringBuilder() for (x <- xs) { builder.append(x) } builder.toString() } join(formatImpl(n, romanDigits)) } def main(args: Array[String]) { assert(format(11) == "XI") assert(parse("MDCCCLXXXVIII") == 1888) assert(parse("mdccclxxxviii") == 1888) assert(parse("McmXLv") == 1945) try { format(0) assert(false) } catch { case _: Throwable => Unit } try { parse("A") assert(false) } catch { case _: Throwable => Unit } } }