Aria のページが wikipedia から削除

ディスカッションによると, notable じゃないから削除すると.
ポリシーにあってないということだ.
"ここはダウンロード可能なソフトウエアを列挙する場所じゃないよ" ということだが, それはそれで最もな意見で興味深い.

しかしどこまでいけば notable なのかはよく分からないよね.

HDD が認識される順番

この前, dist-upgrade したときから, それまで /dev/sda と認識されていた HDD が /dev/sdb として認識されるようになった.

この件については, grub の menu.lst を /dev/sda -> /dev/sdb することで様子見していたが, mount コマンドを実行すると, /dev/sda1 が / にマウントされている. しかし実際これは /dev/sdb1 であった. こういう不可解な現象を放っておくと後で痛い目を見る確率が高い. よって詳しくみてみることにした.

私の PC には, SATA と PATA のそれぞれ一台ずつ HDD が搭載されている.
SATA がいつも使っているもので Linux はここにインストールされいる. PATA はデータ用である.

まず, BIOS はどういう順番で返しているのかというと, grub shell で find /boot/vml で補完すると (hd0,0) とかえってくるので,

hd0 SATA
hd1 PATA

であることが分かる.

次に Linux ではどうかというと, dmesg を見てみると, sda は PATA, sdb は SATA になっている.

menu.lst の修正の仕方は間違っていなかったということになる.
mount コマンドでの表示がまずかったのは, grub の device.map が,

(hd0) /dev/hda
(hd1) /dev/hdb

となっていたためであった.

(hd0) /dev/hdb
(hd1) /dev/hda

とすれば正常な表示になる.

最後に, resume デバイスがない云々のエラーは, /etc/initramfs-tools/conf.d/resume の中身を修正して, linux-image のパッケージを dpkg-reconfigure すれば直った. しかし, menu.lst はあいかわらず, /dev/sda で出力するしてくれるので, grub が menu.lst を更新する度に修正をしなければならない. この件についてはまた後日.

__func__ in C++

関数名を得るマクロ __func__ は C99 でスタンダードになったようだが, C++ ではスタンダードなんだろうか ?

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1642.html

この記事ではまだのようだが, これ以降の展開が分からない.

gcc では C++ でも __func__ が使えるし, なにより, __PRETTY_FUNCTION__ というのも使える.

http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html

__PRETTY_FUNCTION__ はクラス名とシグナチャまでつけてくれるからこれがベストだけど, gcc 独自だよね.

open-std.org の記事の通り, C++デバッグ環境の整備が欠けていますね.

google-perftools-1.2 をインストールする

debiangoogle-perftools の amd64 は長らくアップデートされていないし, リンクして実行するとエラーはいてプログラムがストップしたりして困り者である. そこで最新の 1.2 をビルドしてインストールすることにした.

ダウンロード後, アーカイブを覗くと packages ディレクトリの下に deb.sh がある. 中身を見ると, まずは configure してから make dist する必要があるようだ.

http://code.google.com/p/google-perftools/issues/detail?id=42
amd64 では libunwind か frame-pointers が必要だということなので, 今回は frame-pointers を使うことにする.

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=487374

にしたがって, packages/rules に

DEB_CONFIGURE_EXTRA_FLAGS := --enable-frame-pointers

を追加するがうまくいかず, 結局, configure への引数に直接 --enable-frame-pointers を追加した.

その後, deb.sh を実行するのだが, 何も引数なしで実行すると make dist で作成したアーカイブからパッケージ名とかバージョンとかを類推すると書いているが ln でエラーになるので明示的に与えた.

./deb.sh google-perftools 1.2

これで無事パッケージをビルドできた.

メモリを 4GiB 以上積んで 64Bit の恩恵を謳歌してはいるが, 386 だとこんな面倒しなくていいだよな.

pulseaudio

久々に debian で dist-upgrade を強行. その過程で pulseaudio がインストールされた. なにやら esound みたいなもののようだ. しかし ac3 のパススルーや SPDIF の出力ができないようだ. フォーラムとかで調べたら分かりそうだが, ubuntu のフォーラム読んだ後の私の解決方法は, pulseaudio をアンインストール. これで問題は解決された.

その他は, ブートのときにハードディスクがいままで /dev/sda で認識されていたのが /dev/sdb に認識されるようになった. ときどき元に戻るが, ほとんどは /dev/sdb として認識されているようだ. ひとまず grub の menu.lst を s/sda/sdb/ して様子見.

aria2 1.3.2 をリリース

先ほど aria2 1.3.2 をリリースした.
BitTorrent のダウンロードが終了しないバグを修正した点が大きなポイントである. このバグはユーザーからの報告で判明したのであるが, ピースの数がある条件を満たす場合だけに表面化するものであった.
またこのバグは, 1.3.1 でのパフォーマンス最適化のための変更で混入したものであった. ChangeLog をみるに, 2008-03-28 の最後のコミットである. どんな処理かというと const char* ポインターで指すポイントから n 個のビットまでの連続領域で何個ビットが立っているかを勘定するというもの. 怠惰な私は 1 バイト = 8 ビットと当然のように前提をおいてはいるが, 当然 n は 8 の倍数にならない場合がある. 以前は最後のバイトは 0 のビットがパディングとして詰められてると仮定していた.
問題の変更では, きっちり指定ビットまでしかみないように変更したのだが, テストケースが不十分だったようである.

このネタと関係なく, 開催自体はもう終わっていたのであるが, ネット業界滋賀県人会というのがあるのを知った.

テンプレートの型を出力する

C++ Template Metaprogramming の練習問題 2-4

テンプレート パラメータの型をストリームに出力するテンプレート クラス type_descriptor を書け. ただし, パラメータは char, short, int, long からなるコンパウンド型のみに限定してよい.

さらにここでは, cv-クオリファイヤを const だけに限定することにする. 2-4 は boost なしでクリアする問題です.
例えば, type_descriptor はこんな具合に動作する.

std::cout << type_descriptor<int>() << std::endl; // prints "int"
std::cout << type_descriptor<long const*&>() << std::endl; // prints "long const*&"

戦略は, type_descriptor をパラメータひとつとるテンプレート クラスとして宣言して, type_descriptor を引数にとる operator<< を定義する. type_descriptor の static メソッド out で出力処理をすることにする.

template<typename T>
struct type_descriptor;

template<typename T>
std::ostream& operator<<(std::ostream& o, const type_descriptor<T>& t)
{
  return type_descriptor<T>::out(o);
}

そして, type_descriptor を特殊化していくことにする. まず, int で特殊化してみる.

template<>
struct type_descriptor<int>
{
  static std::ostream& out(std::ostream& o)
  {
    return o << "int";
  }
};

これで

std::cout << type_descriptor<int>() << std::endl;

コンパイル可能になる. 同じように short, long, char についても特殊化する.

次に const, pointer, reference で部分特殊化する.

// Partial specialization for const type.
template<typename T>
struct type_descriptor<T const>
{
  static std::ostream& out(std::ostream& o)
  {
    return type_descriptor<T>::out(o) << " const";
  }
};

// Partial specialization for pointers.
template<typename T>
struct type_descriptor<T*>
{
  static std::ostream& out(std::ostream& o)
  {
    return type_descriptor<T>::out(o) << "*";
  }
};

// Partial specialization for references.
template<typename T>
struct type_descriptor<T&>
{
  static std::ostream& out(std::ostream& o)
  {
    return type_descriptor<T>::out(o) << "&";
  }
};

これで, long const*& みたいなやつにも対応できた. よしよし, いまのところ順調だ. 引数をひとつ取る関数に対する特殊化もやってみよう.

// Partial specialization for functions taking 1 argument.
template<typename R, typename A>
struct type_descriptor<R(*)(A)>
{
  static std::ostream& out(std::ostream& o)
  {
    type_descriptor<R>::out(o) << "(*)(";
    return type_descriptor<A>::out(o) << ")";
  }
};

これで, long& (*)(char*) も片付けることができるようになった. 残りはなんだ? 配列やってみようか.

// Partial specialization for arrays with storage size
template<typename T, std::size_t N>
struct type_descriptor<T[N]>
{
  static std::ostream& out(std::ostream& o)
  {
    return type_descriptor<T>::out(o) << "[" << N << "]";
  }
};

type_descriptor() は long[10] と出力するね. OK.

だけど type_descriptor() とすると long[2][10] と出力されるね. これはどうすればよいかな?