Namespace Accident
Home >> Note >> Namespace Accident

名前空間に関する事故

私の分野では,ns-2 というシミュレータを使って性能評価をしたりします. 今回は,そのns-2のソースコードに手を加えていたときの話.

mapを使いたくて,#include<map>と書いたのですが, インクルードしただけで突然次のようなコンパイルエラーが現れました.

/usr/lib/gcc/i386-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo
base.h: In function `const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = Tra
cedInt]':
tcp/tcp-fs.cc:68:   instantiated from here
/usr/lib/gcc/i386-redhat-linux/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo
base.h:177: error: no match for 'operator<' in '__a < __b'

不思議に思い,エラーの元となったソースファイルを開いてみると,問題となっているのは maxseq_ = max(maxseq_, highest_ack_); という記述のようです. これは,非常に嫌な予感がします.using namespace std;の記述もないのに, 名前空間指定なしでコールされているmax()関数.さらに追ってみると, やはりといった感じで原因を突き止めることができました. 原因はtemplate.hというヘッダファイルにある以下の定義でした.

inline int max(int a, int b)
{
    return a < b ? b : a;
}

STLのalgorithmで提供されているものと同名の関数がグローバル名前空間に定義されていたことで, mapと一緒にalgorithmがインクルードされた際におかしくなってしまったのだと思われます. これに加えて,明示的なキャストを怠ったことも災いして,コンパイルエラーが発生してしまったようです (highest_ack_は,TracedIntというns-2で独自に定義された型の変数で,template.hには, この型を引数とするmax()関数は定義されていない).

そういった訳で,今回の事例で得られた教訓.

ns-2もひどいな,と感じる部分が多々存在します.