もしコンパイラを全世界で同時にうっかり削除してしまったら、元の状態に復旧できるのだろうか?

思考実験として、全世界の人が同時に、自分の持っているコンパイラやインタープリタなどの実行ファイルをうっかり全部消してしまったとしよう。そうするとそれ以降、ソースコードが残っていても、コンパイラ自身も含めてどのようなプログラムもコンパイルできなくなってしまう。この状況から人類は元のコンピュータ文明を復旧することができるのだろうか?

僕は結論としては、かなり簡単に復旧できると思う。ここではその手順についてちょっと考えてみよう。

コンパイラのバイナリファイルが全部消えてしまった後、復旧のために目指すべきマイルストーンは、おそらくCコンパイラを元に戻すことになるだろう。Cで書かれたプログラムはOSやコンパイラ自身を含めてたくさんあるので、そこを起点にすれば、たくさんのプログラムを芋づる式に復旧していけるからだ。

ほとんどのCコンパイラはCかC++で書かれている。最近のGCCやClangは巨大かつC++で書かれていて、これをコンパイルするのは辛いので、かなり昔のシンプルなCコンパイラ、たとえばpccをコンパイルするのが最初の目標になるだろう。ただしpcc自体もCで書かれているので、まずはpccをコンパイルできるレベルのCコンパイラを、Cを使わずに書かなければいけない。

そのようなCコンパイラをバイナリエディタを使って機械語で一気に書くのは無理なので、まずは機械語で、すごく簡単なアセンブラを書くことになる。このアセンブラはリッチな機能を持った現代的なアセンブラである必要はなくて、機械語よりはマシ、というレベルでかまわない。次にそのアセンブラを使って、もうちょっと使いやすい別のアセンブラを書き、必要ならばそれを使って別のもっと使いやすいアセンブラを書くということを繰り返して、ある程度使い物になるアセンブラを完成させる。

その次に、そのアセンブラを使ってCのごく小さなサブセットのコンパイラを書く。一度それが完成したら、そのCのサブセットを使って、そのCサブセットコンパイラ自体のコードを書き直すことができる。サブセットとはいってもアセンブリよりはずいぶん書きやすいだろうから、書き直すことでコンパイラの開発効率はずいぶん上がるはずだ。

そのあとにサブセットに本物のCの機能をどんどん足して行くのだが、機能を追加するたびに、その新しい機能がコンパイラ自身のコードを書くときにも使えるようになるので、どんどんコードを書くのは簡単になる。機能追加を繰り返していけば、ある時点で自作Cコンパイラがpccをコンパイルできるレベルに達するはずだ。

pccをコンパイルしてしまえばあとはかなり簡単だ。pccで現行世代のGCCをコンパイルすることはできないが、ある程度古いGCCならできる。つまり昔のバージョンからGCCを芋づる式にコンパイルしていけばいい。何回か繰り返せば最新のGCCをコンパイルできるはずだ。これでほとんど復旧は完了したようなものだろう。

この手順ではCコンパイラを書くステップが難しいのではないかと思うかもしれないけど、特定の少数のプログラムをコンパイルできる程度のCコンパイラを書くというのは、そこまで大変でもない。一度pccをコンパイルすることに成功すれば、pccでpccをコンパイルし直すことができるので、一度そのマイルストーンに達したあとは、自作コンパイラの低いクオリティはどこにも痕跡が残らない。だから、自作コンパイラはそれ自身とpccだけをかろうじてコンパイルできるレベルでかまわないし、最適化などは全く実装する必要がない。

世の中にはすごいプログラマがたくさんいるので、仮にコンパイラがすべて消滅しても、上のような手順で2週間くらいで元の状態に復旧できてしまうのではないかと思う。

プログラミングのよくある疑問として、CコンパイラがCで書かれているなら最初はどうやってコンパイルしたのかというがあるけど、答えは、上のように徐々にブートストラップしていったのだ。この思考実験はコンピュータの仕組みを学ぶためにはわりと悪くないお題なのではないかと思う。

55

Rui Ueyama

コメントを投稿するには、 ログイン または 会員登録 をする必要があります。