Subject: どのコンパイラを使うべきか Date: 2000/12/23 Author: ohkubo@ist.aichi-pu.ac.jp ここでは、以下のコンパイラについて議論する。 ・LSI-C 86 for WW ・Turbo-C 2.01 ・Turbo-C++ 1.01 ・Visual C++ 1.5 ・Borland C++ Suite 次のコンパイラについては情報が不足している。 ・Dev86DOS (ELKSプロジェクトの一部) ・WATCOM C++ 次のコンパイラは 16bit コードを生成しないので使えない。 ・Visual C++ 6.0 ・Borland C++ 5.51 ・cygwin/djgpp gcc ここでは、8086 のコードを生成できる、上に挙げたコンパイラを比較する。 著者の偏見と誤解が多く含まれているが、指摘によりそれらは修正されていく だろう。より価値のある文書にするための、これを読んだ者からのフィードバッ クを期待する。 0. WW 用コンパイラを比較するポイント 0-1. セグメント 8086 にはセグメントという厄介なハードウェアと、メモリモデルという概念 がある。WW では、データセグメントをカートリッジのRAM領域に、スタックセ グメントをCPU内部のRAM領域に設定する(ようにスタートアップを作らなくて はならない)。また、メモリの節約と速度の向上の為に、極力 near ポインタ を用いることが志向される。(するべきであるとはここでは主張しない。)その ためには、コードは far で、データは near で指示できる small メモリモデ ルが適している。ここでは、データセグメント(DS)とスタックセグメント(SS) が同じであるという仮定がコード生成において使われる。すると、SS に存在 する auto 変数の & を求めると、DS 内のアドレスと混同してしまう。これが いわゆる DS!=SS 問題である。アドレスを取るときに far でとるようにすれ ばよい、と思うかもしれないが、C では配列は内部ではポインタで扱われてい ることから、事態は深刻なものとなる。 この問題に対して、オフィシャルの FAQ には「問題を回避できます」と能天 気な説明がなされているが、これを意識してコーディングするくらいならアセ ンブラでコーディングするほうがマシなくらい、意図しない実行時エラーを連 発してくれる。DS==SS を仮定しないでコードを生成できるコンパイラを選択 するべきである。 0-2. 文字列の扱い WW にはえりさフォントが搭載されており、テキストBIOS を介して Shift_JIS で曲がりなりにも日本語を表示することができる。しかし、Shift_JIS という いびつなエンコード体系のせいで、2バイトめに \ や % を含む文字列の扱い という問題が生じた。 日本語版のコンパイラでは、ストリングの Shift_JIS 表記を意図どおりに扱っ てくれるものがある。手軽にコーディングするためにはあれば便利な機能では ある。 0-3. インラインアセンブリ 性能向上のため、アセンブリでコーディングしたいとき、特に asm 構文で コードを埋め込むことができるかどうか。 0-4. バイナリの配布条件などに制限がかけられていないか 0-5. 価格など、入手容易性 0-6. その他、LFN 対応とか? 1. LSI-C 86 for WW LSI-C for WW は、WW のパッケージにバンドルされている。CD からアーカイ ブファイルを展開すると、ツールやヘッダなどと同時にインストールされる。 よって、最初は素朴に LSI-C を選ぶユーザが多いだろう。副次的な結果とし て、オフィシャルからの情報、WEB で得られる情報、はまず LSI-C をターゲッ トとすることになり、さらに正の帰還が発生する。 LSI-C for WW が for WW であるのは、Turbo-C 2.01 のオブジェクトコードと 相互にリンクできるように、パラメタ渡しの方法を C 言語標準のものにした という点につきる。よって、LSI-C 86 の持つ利点である「レジスタを用いた パラメタ渡しによる高速な関数呼び出し」は失われている。 WW の最初の CD-ROM には 32bit 版のバイナリが含まれていたが、これは「手 違いにより混入したもの」だそうで、16bit 版のライセンスしかユーザには与 えられない。この 16bit 版は内部のワーク領域が非常に狭く、関数の内容が 少々複雑になっただけで Out of Memory となることが報告されている。 1-1. DS!=SS LSI-C for WW は、for WW と名乗りながら WW 特有のメモリモデルである DS!=SS 問題に一切対処していない。 1-2. 文字列 LSI-C は、文字列の解釈のモードを ASCII, MS漢字コード, 中国語および台湾 語コード, 韓国語コード, から選択できる。 1-3. アセンブラ アセンブラ r86 も同梱されており、インラインでも別ファイルとしてもアセ ンブラも自由に使うことができる。 1-4. ライセンス上の制限 付属の LICENSE.TXT には > 6. プログラムの配布 > 本ソフトウェアの使用により作成されたプログラムは、使用者または第三者に > よって、当社に事前の承認または報告を要すること無く、配布することができ > ます。[中略] また、配布の際に手数料と認められる額を超える金銭の授受を > 禁じます。 とあるので、商品や対価を要求するオンラインソフトの作成には使えない。 (「コーディングの手数料」という言い方が認められればどうか知らないが。) 1-5. 入手性 WW にバンドルされているので、誰でも持っているはずである。 1-X. 結論 情報・ユーザが多いという利点はかけがえのないものであるが、性能の観点か らは全く勧められない。なし崩し的に LSI-C ユーザが(現在 windoze がはび こっているように*1)増えることを阻止することがこの文章の主目的である。 (*1) といいつつ、ここで紹介しているのは doze 用ばかりだとか、筆者は今 doze マシンに向かってこの文章を書き下しているとか、世の中は矛盾に満ち ている。 2. Turbo-C 2.01 Turbo-C 2.01 は Borland 社の製品で、現在は Antique Software として無償 で後悔されている。WW の CD-ROM に含まれるものはダウンロードできるアー カイブそのものである。さらに、オフィシャルに提供されるライブラリ・ヘッ ダ・スタートアップルーチンなどは、LSI-C for WW とともに Turbo-C 版も提 供されるので、第2のオフィシャルなコンパイラといえる。 出力コードの最適化性能などの点で、LSI-C よりよいというファンも多い。 WonderSwan の CPU は V30MZ という 186 互換のものであるが、TC2 は 186/286 の拡張命令を利用するオプションがある。 2-1. DS!=SS TC2 も DS!=SS 問題には対応していない。 2-2. 文字列 TC2 は外国産コンパイラであり、Shift_JIS コードのことは一切配慮しない。 2-3. アセンブラ TC2 はインラインアセンブリに TASM を要求する。しかし、現在 TASM は単体 では販売されていない。代用(というか、本家の) Microsoft MASM が Windows DDK の一部として無償で利用可能になっているので、これを用いることができ るだろう。 2-4. ライセンス上の制限 (確か対価を要求することもできたと思うが、ドキュメントが見当たらない & 見つかっても英語なので、後回し。) 2-5. 入手性 WW に同梱されている。 2-X. 結論 オフィシャルでも多少サポート不足である点は否めないが、同梱されている二 つのコンパイラから選択するならば、TC2 の方が性能は高いと結論できる。し かし、その選択をするなら、もう1歩進んで、次の TC++1 が選択できるはずで ある。 3. Turbo C++ 1.01 TC++1 は、TC2 の次のバージョンである。このため、TC2 の動作する環境を設 定して TC++1 に置き換えてやれば、そのまま運用できる。これは、TC++1 を C コンパイラとして使う分には、上で述べた TC2 の利点はそのまま引きつい でいるという意味である。しかし、スタートアップなどは未整備なので、C++ として使うことは考えないほうがよいだろう。 TC+1 は WW には同梱されていないが、TC2 同様に Borland から無償でダウン ロードすることができる。WW にバンドルされなかった理由は「C++ の機能を 使えないから」だけだったと想像されている。 3-1. DS!=SS TC++1 には、メモリモデル指定のオプションの修飾子として "!" があり、こ れで DS==SS の仮定をしないことを指示できる。また、near ポインタの修飾 子として _cs, _ds, _ss というシンボルがあり、セグメント制限を逸脱した ポインタの使用をコンパイラが警告してくれる。 3-2. 文字列 TC2 と事情は同じ。 3-3. アセンブラ TC2 と事情は同じ。 3-4. ライセンス上の制限 TC2 と事情は同じ、はず。 3-5. 入手性 Borland の Antique Software Museum で登録し、無償でダウンロードできる。 アーカイブのサイズは ??MB 3-X. 結論 オフィシャルにサポートされている TC2 と互換で使える、DS!=SS 問題に対応 している、無償である、という数々の利点により、WW ユーザの標準コンパイ ラとして普及するべき存在であろう。 # しかし、それだけでは Macintosh もホンダも売れない。 # せいぜい「違いがわかる人の選択肢」になるだけだ。 4. Visual C++ 1.5 Microsoft の最初の C++ コンパイラである。Windows の 16bit DLL やデバイ スドライバを開発するための 16bit コンパイラとして、現在でも Microsoft オフィシャルなコンパイラである。 4-1. DS!=SS 16bit DLL は、スモールメモリモデルに近く DS!=SS という、WW の動作環境 とよく似た環境で動作する。このため、DS!=SS に対応したコードを生成でき る。 4-2 文字列 VC++ 1.51(J) ならば、MS漢字コードに対応しているのではないだろうか。 4-3. アセンブラ インラインアセンブラは利用可能である。その際、MASM が必要なのかどうか はわからない。 4-4. ライセンス上の制限 厳密なことをいうと DLL 以外書いてはいけないのかもしれないが、 さすがの MS もそこまできついライセンスを敷くだろうか。要調査。 4-5. 入手性 MSDN の最上位のサブスクリプションをしていると、現在でも入手可能らしい。 4-X. 結論 古いパッケージを持っているか、MSDN に加入していて入手できるならば 選択に値する。そうでない場合にわざわざ選ぶ利点は少ない。 5. Borland C++ Suite Inprise 社が、Museum に片足をつっこんだソフトをパッケージにしてオンラ イン販売しているもの。15,000円で Borland C++ 5.0(J) と TASM が入手でき る。 TC2 の遠い子孫なので、TC++1 同様に WW の開発に利用可能であるはず。 ただし例によって、C++ としては使わないほうが無難であろう。 5-1. DS!=SS TC++1 の後継なので、"!" オプションが指示できる。 5-2. 文字列 日本語版のコンパイラを使えば、対応しているだろう。 5-3. アセンブラ BC++5 に内蔵された BASM と、独立した TASM の両方が利用できる。 C++ からアセンブラソースを出力することで、インラインでも TASM で コーディングできる。 5-4. ライセンス上の制限 商品だし、特に問題ないだろうが、要確認。 5-5. 入手性 オンラインで販売されている。非常に優秀な処理系のパッケージであり、 Windows アプリケーションを作るなど他の用途にも使え、15,000円出す価値は あると考えられる。しかし、そうでない「しわい」プログラマのために、これ を標準とすることは避けたい。 6. Dev86DOS (ELKSプロジェクトの一部) OpenSource の x86 コンパイラであり、現在メンテナンスが続いているおそら く唯一の環境。非 Windows OS で、DOS box を用いて LSI-C を動かすなどと いう実り少ないことをするより、これが使えるようにする方が王道。 7. WATCOM C++ OpenSource となることで、Windows でなくても利用可能、WW に特化した機能 の追加、などが期待でき、WW 用の最高のコンパイラになる可能性を秘めている。 8. 16bit コードを生成できないコンパイラ ・Visual C++ 6.0 16bit コードのために、今もなお VC++1.5 が供給されている。 ・Borland C++ 5.51 フリーでダウンロードできるが、WW には使えない。 ・cygwin/djgpp gcc もともと 32bit を必要とする。djgpp には製作途中で放棄された 16bit コン パイラがあるが、全くサポートされていない。そんなものをいじるくらいなら Dev86 や WATCOM をベースにする方がよいだろう。