更新履歴兼雑記 2002年10月分

since: 2002-10-01 update: 2002-11-01 count:
最新のものはこちら
Oct 29, 2002

[Program]: iterator_adaptors

loopの数ですが、 私がバイトで for ループを置換していった時はほとんど消えました。 消えないような中身のでかいループはメソッド化すべき、 という一種のバロメータになるのがなんとも。

あわわこんなことが。 いいかげんちゃんと勉強した方がいいなあ。 cvs とか make とか vi とか zsh とか screen とか…

[Program]: robocode

面白すぎ。一週間程はまってた。 週末は久しぶりに一日に30時間以上プログラム書いて疲れた。 結構強いのができてきた。でもまだまだ遊べる。 ジャパンカップでザウルス貰いたいなあと夢見る今日この頃。 無理っぽい。

これで Java でなければなあ。 まあ Java だからロボットを手軽にダイナミックロードできるんだけどね。 c++ は一定こだわりがあるけど、 Java は全く無いので恐しく適当にコーディングしていく自分を発見。

とりあえずしばらく他の部分はおろそかになる予感。 boost-dev ML も、まあ、 メール 500通程度なら溜めても処理できるだろう。たぶん。 とか思って放置気味。

[Program]: 履歴

久しぶりの Java だなあ。 バイトでアプレットいじってて以来だから半年ぶりくらいか。 私の Java 経験って 200時間弱位だろうか。ずいぶん少ない気がする。 まあ趣味で書いたことは一度も無いからか。 Java でコードを書いてた時間より長く遊んだゲームが 10タイトルはあるなあ。

とか思ってるとじゃあ c++ は何時間位だろうか、 と考えても想像もできなかったのですが、 とにかくコード書き始めてから 2年ちょいしか経って無いことに気付く。 もっと長い付き合いだと思ってたんだけど。 プログラミング言語 c++ を全部読んで OO な気分になったのが二年前。 そのちょっと後バイトで STL コンテナ/イテレータ。 半年後 STL アルゴリズム/アダプタ。 もう半年で boost。 んでもう半年で Loki その他経由でメタプログラミング。 半年単位でc++は感動的な物を見せてくれるらしい。 次は何だろうか?


Oct 22, 2002

[Update]: sevilwm

バグ指摘を頂いたので。 二ヶ月以上前に頂いたパッチを今ごろ加えてリリース。 すっかり記憶から抜け落ちてました。すいません。

暇を見て c++ 部分を c で書き直したいなあ、などと。

[Program]: boost::lambda の続き

私の表現が適当だったので、誤解が少し。 5%の差というのはオリジナルのソースでの話です。 改行を外してからは全く差が無かったです。 つまり、私達の間で最終的な結果は 相違無しということでめでたしめでたし、です。

boost::bind も boost::lambda も何回も関数呼びだしするけど、 全部インライン展開されるんじゃないでしょうか? 比較するコード を書いてみたんですが、 私の環境では最適化 -O で全部同じ速度になりました。 最適化しないと、

lambda 0.64s
bind   0.54s
normal 0.52s

ってとこでした。 ラムダオブジェクト作りまくりでオプション無しでは最適化しきらん、 ってとこだと思います。

しかし inline は魔法ですな。

その通りだと思いました。 じゃあちゃんと速度差が出まくってるのはなんでなんだろう? 出力先は /dev/null だからそのへんは考えなくていいとして、 iostream は出力の方はたいした処理をしてない、ってことかなあ。 まあそんな気がする。きっとそうだ。

[Program]: インターフェイスは何よりも考えるのがしんどい。

なかなか深く悩まれてますな。 OO的には setter なんだろうけど、 C的にはパラメータ構造体が良い気がします。 不思議。 多分 X なんかが後者を多用しているから刷り込みかなあ。 でも OpenGL は前者が適切な気がする。 この辺りを分かつものは…言語化しにくい。

…私はどうせ相手はプログラマ(しかも大抵自分のみ) なんだから適当でいいんだよ、 という結論に落ちます、大抵。 きちんと考える zinniaさんは立派だなあ、と思ったり。


Oct 20, 2002

[Program]: 環境の差?

うーん。 私の環境ではそこまでの差は出なくて、 5%位の差でした。

if (_1 % 2 == 0) cout << _1 << "は偶数" << endl; else cout << _1 << "は奇数" << endl;

私んとこでは "は偶数" を "は偶数\n" に変えたら似たようになりましたが… それが真の原因かは自信無し。

GDB に catch というコマンドがあることを今頃知った。 でもうまく動かん、何故。


Oct 18, 2002

[Update]: boost user

MPLに加筆。 継承さえすれば後は気軽に使える dumper。 MPL Sequence/Iterator の解説のため作成。 MPL最高。 使うぶんには簡単なのがなんとも。

内容紹介

class Class : public std::string,
              public Dumper<mpl::list<std::string, char,
                                      int, std::string, char>
{
    Class() : std::string("derived from string") {}
    char c1;
    int i1;
    std::string s1;
    char c2;
};

int main() {
    Class c;
    c.c1 = 'a';
    c.i1 = 2;
    c.s1 = "hello world";
    c.c2 = 'b';

    c.dump();
}

で、出力が

3221222032: derived from string
3221222036: a
3221222040: 2
3221222044: hello world
3221222048: b

どうだ、えへん。

intel コンパイラ優秀っす。MPL を余裕で通しやがった。 でも gcc との似てるのがどうにも気になるなあ。 少なくとも、「ソースを参考にする」レベルのことは絶対やってる。


Oct 16, 2002

[Program]: OCamlSDL

で少し遊んでみた。 マンデルブロー集合。 コンパイルは、

> ocamlopt -c -I /usr/lib/ocaml/sdl mandel.ml
> ocamlopt -cclib "-L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL -lpthread -lSD
L_ttf -lSDL_image -lSDL_mixer -lpng -lz -lm" -cclib "-L/usr/lib/ocaml/sdl -lstub
" -o mandelocaml /usr/lib/ocaml/sdl/libstub.a /usr/lib/ocaml/sdl/sdl.cmxa bigarr
ay.cmxa mandel.cmx

でやっている。 噂通り、とても速い。 最適化オプション -O の g++ で作った等価なコードと比べてみたが、 一割も遜色が無かった。 最適化オプションが無いと話にならない。 素晴らしい。

ただ残念なのが、OCamlSDLがまだまだ未完成であること。 Eventが足りなかったり、今回気付いたのだが、 (set/get)_pixel がバグ入りだったり。 CVSのヤツは随分良くなっているようだが、 ./configure; make ができなくて、結構めんどくさそう。 これからに期待。

[Wheel]: Makefile テンプレート作成ツール。

私は趣味で書いてるコードの七割位が テストコードというか、なんらかのお試しコードな気がする。 で、その時に、

> g++ -o hoge hoge.cc

とか打つのが結構めんどい。 何がめんどいって、hogeが二回あるんだもん。 まあ、

> g++-o () { g++ -o $@ $@.cc }

とかしといたら良いか、とも思ったのだが、 まあ、これじゃ芸が無いってことで小物を作ってみた。 例の如くどこかに似たようなものがあるんじゃないかなあ、 とびくびくしながら。 フィーリングコンパイルツール kati、とその設定ファイル .kati

インストールはパスの通ったところに kati を置いて chmod 755。 後はホームディレクトリに .kati を置くだけ。

結構賢い動きをする。 例えば、

> cd SDL-1.2.4/test 
> kati

だけで、configure もへったくれもなく、たくさんの実行ファイルができる。 当然、.kati の SDL の項目は正しく設定されていないといけないが。

対象を一つにしぼることもできる。 というか当初の目的がこれ。

> kati testsprite

なり、

> kati testsprite.c

これで、testsprite だけをコンパイルできる。

boost/libs/regex/src のように、main が無いファイル群の場合、 オブジェクトファイルだけを作る。

/* a.c */
int a();

int main() {
  return a();
}

/* b.c */
int a() { return 0; }

このような場合、ちゃんと以下のようにやってくれる。

cc -c a.c -g -W -Wall -ansi -pedantic 
cc -c b.c -g -W -Wall -ansi -pedantic 
cc -o a a.o b.o   -g -W -Wall -ansi -pedantic 

.kati に書いてあるのは、各行の一番左が項目名、 残りは項目に対応したオプション。 ソース内のインクルード文に、項目名文字列が含まれている場合、 そのオプションが自動的に指定される。 SDL やら boost がコンパイルできたのはそのため。

明示的に項目を加えることもできる。

> kati SDL
   or
> kati hoge.cc SDL

+ を付けることで、項目を削除することもできる。 例えば testsprite は -W -Wall がうるさいので、

> kati testsprite +w

default という項目名はデフォルトで読み込まれる。 $ で始まるオプションは、その項目名を取り込む。 default は -g -W -Wall -ansi -pedantic になっている。

コンパイルは Makefile を作ることによって行われている。 Makefile.kati という名前で保存されている。 これを Makefile の元にすると楽ができそうだ。

あとコンパイルオプションを付け加えることもできる。

> kati hoge.cc -march=i486

あと、全オプションはフィーリングで CFLAGS と LDFLAGS に分配される。

文法的には、以下のような感じ。

kati [ターゲット] [追加/削除項目] [追加オプション]

んなとこ。 まあ少なくとも私には便利そうだ。 でもあちこちで雑をしているから変な動きもあると思う。


Oct 15, 2002

[Update]: boost user

uBLASの解説、書きました。 何故か expression template 特集。ベンチマーク。 二個目の計算結果に小びっくりしました。

うーんそうかなあいやそれは無いだろう(02/10/14参照)。 なんか競合してそうで微妙にやっとることが違うのは確かかも。 うまく表現できないが。 いずれにせよ、date_time, format, multi_array の解説が 無いに等しいのはいかんなあ。 でもやっぱりあまり興味無いコンポーネントなので やっぱり書きませんすいません。 つうか二度と興味の無いことを書こうとしませんすいません。


Oct 12, 2002

[Update]: boost link

1.29.0 が来たので。 date_time と format はもうちょっと真面目に書きますすいません。

K.INABA. さんも更新されました。 私が適当に書く必要は無かったか。


Oct 10, 2002

[Update]: boost user

1_29_0 の新コンポーネントの解説を先走ってやってみました。 非常にいい加減。signals だけは結構真面目。

[Program]: boost と long long

こいつはあっしも悩みの種でした。 んで、解決法は知ってるつもりだったんで、 1_28_0 に対する patch を作ってみました。 たぶんこれで -ansi -pedantic が通るはず。

そういや今まで誰にも patch の作り方って 教えてもらって無いから適当なんだけど、 これが適切なやり方なんだろうか?

仕組みは -ansi で現れる、__STRICT_ANSI__ が on になってたら、 BOOST_HAS_LONG_LONG を off にして、 後は BOOST_HAS_LONG_LONG 以外の条件で long long を使うかどうかを判定しているコードを ifdef BOOST_HAS_LONG_LONG で包んだだけです。

これ、boost-dev に投げたら採用してくれるかなあ。

あと、-ansi だけだと M_PI とかが消えるだけで、 チェックは変わってないと思います。

何故に cl.exe?と思ってしまいました。 コンパイラだけなら bcc32.exe に決まっておろう、と。 wine はいいですなあ。 あと、Kylix3 が良いコンパイラなのは Borland C++ そのまんまだからだと思います。たぶん。


Oct 09, 2002

[Program]: intel c++ compiler

前回の続き。 前回眠い時に書いてたからなんか電波な文章だなあ。 とりあえずプログラムが一部間違ってたからそこだけ修正。 さて、どこでしょう?

前回の例では、 icc では template template parameter だけダメでした。 ずいぶん前に実験した時は partial specialization がダメだったような気がしたんだけどなあ。

なんつーか鬼のように c++ & linux に順風ですなあ。 放置しているこれ はこういう比較がやりたかったんだよなあ。 確か。 選択肢と判断材料を提示する、というか。 現状ではただかき集めただけだし、だんだん古くなるし。

c++ library に関してもそういうものがあったら良いと思う。 無きゃ java に勝てっこない。 いや、勝たなくてもいいんだけどね。

私的には最近心は ocaml なのですが。 こんないい言語があったなんてねえ。

[Program]: SDL_SaveMovie

なんか自信無いんですが… こう、がんがん描画しては画面を消し、 ってのを繰り返すゲームには適用不可ですか? たぶん画面を消去して真っ暗になった時に、 SaveJPG が呼ばれちゃうと思うんですが…

一定時間ごとに画像をひっぱってくるモードと別に、 クライアントコードが画像をひっぱるタイミングを 指定するモードが必要かなあ、と思うんですがどうでしょう。

最初見た時、相変わらず隙間を埋めるいい仕事だなあとか思って、 早速適当なムービー作ってみようかとしたんですが、 つまづいてしまって悩んでました。

あと、もちろんサンプルはうまく動きましたです。


Oct 07, 2002

[Program]: gcc マンセイ。

gcc 3.3 comming soon? だそうです。 こりゃすごいっすね。 gcc-3 系列になって小さいファイルのコンパイルは遅くなって、 大きいファイルは速くなった、っていうのが私的結論だったのですが、 どっちも速くなってますねえ。 まあ、でもリリースは遅れまくるのが基本っぽいので気長に気長に。 ほんとかなあ

オプションたくさん紹介ありがとうございます。 でもとりあえず -ansi -pedantic は是非。

私は -W -Wall -ansi -pedantic だけでしたが、 結構他にも入れた方が良さげなのがあるんですね。 ちなみに上記オプションだけなら sstream に ちょっと手を加えれば warning ゼロ生活です。

ls /usr/include/g++-3 | grep -v ".h$" | perl -ne 'chomp;print "#include <$_>\n"' > ~/std.cc

気になってたことなんでこんなことしてみました。 嫌になるほど warning が出た上、 warning の方が違うんじゃないかと思うような エラーメッセージまで出たんで少しいじって諦めました。

stlport 使えば良くなるのかなあと思いましたが、 全然変わらず。

  _IO_istream_withassign& operator=(_IO_istream_withassign& rhs)
    { return operator= (static_cast<istream&> (rhs)); }

に対して、

g++-3/iostream.h: In method `_IO_istream_withassign 
&_IO_istream_withassign::operator= (_IO_istream_withassign &)':
g++-3/iostream.h:238: warning: `operator=' should return a reference to 
`*this'

とかはキツすぎ。あと、

g++-3/stl_iterator.h:637: warning: `reverse_iterator<_Iterator>::operator+=
(typename iterator_traits<_Iterator>::difference_type)' should return 
by value

嘘つくなよ。 これは gcc-3.0.4 => gcc-3.1 で修正されとりましたが。 地道に成長していくあなたが好き。 十バージョン近く入れても 200M 足らずなあなたが好き。

[Program]: やっぱり Kylix3 マンセー?

コンパイラをいたぶってみる。

template <class T> class C {};
class C<int> {};

template <template<class> class T> class D {};

class E {
public:
  template <class T> void func(T t);
};
template <class T>
void E::func(T t) {}

void a() {}
void b() { return b(); }

#include <vector>
void test() {
  C<double> c1;
  C<int> c2;

  D<std::vector> d;

  E e;
  e.func(1);
}

partial specialization と template template parameter がオッケーですか。 ついでに VC がダメな void関数での void関数 return と、 テンプレートメソッドの外部定義。 完璧。すげえ。 これはひょっとするとひょっとしますなあ。 ちょいとパフォーマンスとかもしっかり調べてみましょうか。


home / index

全てリンクフリーです。 コード片は自由に使用していただいて構いません。 その他のものはGPL扱いであればあらゆる使用に関して文句は言いません。 なにかあれば下記メールアドレスへ。

shinichiro.hamaji _at_ gmail.com / shinichiro.h