鍋あり谷あり

テーマを決めずに適当に書いています。

今度はコンパイラを殺してみる

ランタイムの自殺プログラムが好評だったような気がするので、今度はコンパイラを殺すプログラムを書いてみる。

template< typename x=int >
struct x{ x::x(){} };
void test(){  x<>x; }

g++ だと、エラー。

declaration of `class x' shadows template parm `class x'

とかいう感じになる。正しい。
Microsoft の cl 13.10.3077 だと「INTERNAL COMPILER ERROR」となり、コンパイラのソースの何行目でおかしくなったとか、そういう情報が表示される。つまり、cl は死亡。

続いて:

template< typename t=int >
struct x{struct t{};};
void test(){  (x<>::t()).int();  }

最初のと似たようなパターンだが、ちょっとあからさまさが少ない感じ。
これも g++ は正しくエラーを出すが、Microsoft cl は、死亡。
テンプレート変数を隠されると死にやすいということなんだと思う。
まあこれでも vc6 の頃の悪夢とは比べようもなくよくできたコンパイラではある。

最後はもうちょっと凶悪な奴。

template< typename a=int, typename b=int >
  struct foo{  template< typename x > struct t{   x m;  };  };
template< typename a >
  struct x : public a::template t< x<foo<a,a> > >{};
void test(){  x<foo<> > x;  }

これは、いつでもコンパイラプロセスを殺せる状態にしてからコンパイルすることをお勧めする。
Microsoft cl だと、メモリ使用量こそ増えないが、CPU使用率100%に張り付いて帰ってこない。ctrl+C を押してもすぐには復帰しないので不安になるが、手元では実行時間と同じぐらい待っていたら帰ってきた。放置したら死ぬのかもしれないが、あまり長い時間は試していない。
g++ だと、メモリ使用量がうなぎ登りになる。どこまで行くかと思って待っていたら:

cc1plus.exe: out of memory allocating 374341720 bytes

で死んだ。
もうちょっと短く書けるような気がしてならないが、もう寝る。

で。
結局、g++ をちゃんとは殺せなかった。ちょっと負けた感じ。