ソースコードのmodularityの低さ(2)

バイナリレベルでの相互呼び出しに関しては、COMでもCORBAでも、まあ何でもいいのだが、それほど実現するのは難しくはない。これと同じことをソースレベルで行なえるかというと、そりゃもう、不可能に近い。

なんでか?

ソースコードが特定のコンパイラ、あるいは特定のコンパイラの特定のバージョンに依存したりしてるからである。

yaneSDK2ndはVC5/6を対象にしていた。yaneSDK3rdはVC6/.NET(7 or 7.1)を対象にしている。yaneSDK4DはD言語だし、yaneSDK4CsはC#だ。これらのソースは、水と油のようになっており、互いに混じり合うことは出来ない。

ところが、バイナリレベルでならば相互に呼び出すことは可能だろう。COMのような大がかりな仕組みでなくとも、DLLをLoadLibraryで読み込んで、そのなかの関数を呼び出すというのでも構わないし、libを作成してバイナリ生成時にリンクしてしまう、というのでも構わない。

プロセッサをPentiumに固定してしまうなら、原則的にバイナリは一種類である。どんなソースをコンパイルしてもPentiumのマシンコードに翻訳されるし、それこそがコンパイラの仕事だからだ。(いまネイティブコードの吐けないC#,Javaのことは考えないことにする)

つまりは、frontendを作ってソースコードを「マシンコードよりの言語」にいったん落とし込んでやれば、それぞれの言語を混交させることが可能になってくるわけだ。「マシンコードよりの言語」って、マシンコードでは駄目なのだろうか?私は駄目だと思う。マシンコードでは、機能が分解されすぎていて、どれが関数で、どれがswitch〜caseかを見分けることすら困難になるからだ。

まあ、仮に、C++JavaD言語もすべてC言語のソースにいったん落として、ごにょごにょ加工することを考える。まあ、GC付きの言語とGCなしの言語とごちゃ混ぜにするとややこしいことになるが、そのへんはいま考えないことにする。厳密に言えば、C++からCへのトランスレータが必要なのではなくて、VC++6用に書かれたソースからCへのトランスレータVC++.NET用に書かれたソースからCへのトランスレータetc..が必要なのである。

この仕組みがあって、はじめて、VC++6のソースとVC++.NETのソースとを混交させることが出来る。VC++.NETの関数から、VC++6のクラスメソッドを呼び出すことが出来るようになるのである。逆に言えば、この仕組みがないから、VC++6用に書かれたソースや、VC++5用に書かれたソースは、もう.NET時代においてはリライトを余儀なくされるわけだ。過去の資産運用なんて、てんで出来てない。新しいコンパイラでは古いコンパイラ用に書かれたコードをコンパイルすら出来ない。これがC/C++言語の実情だ。いかに下位互換性を重視しながら拡張してきたとは言っても、そのへんの事情は実にさぶーいのだ。

この先、こんなことが何度も起こるだろう。.NET用のコードは.NET2005でコンパイルできないとか、.NET2005用のコードは、.NET2008でコンパイルできないとかな..。こんなのはとても正気の沙汰とは思えない。

何故こんなことが起きるのだろうか?それは、ソースコードコンパイラがembedされていないからだ。何を当たり前の、と思われるかも知れないが、コンパイラ本体なんて小さいのだから、もうソースにくっつけちゃえばいいのだ。

..とまあ、そんなことは叶いそうにはないので、もう少し真面目にこの問題について取り組まなくてはならないだろう。(つづく)