LCC-Win32レポート (1997.Aug.03)

久しぶりにGCCのHome page (という言い方は多分、不適切だろうけど……)を見たらgccがバージョンアップされていた。WWW回線は会社からならタダなのでさっそく落としたが、13MBのアーカイブってのにはまいった。でかいのだ。beta18だそうな。
ディレクトリも深い。深すぎる。gdbはTcl/Tkのインタフェースで動くようになってるし。ま、Win95上でXみたいなウィンドウ表示があっさり実現できたという点では感動したけど、元々がDOSなあたしにできたのはせいぜいTcl/Tkのハウツー本を買いに走った、ってだけのことでしかなかったりする(Java本だって埃被ってるってのに、なもん買ってどうする、という自嘲の念は一瞬だけ脳裏をよぎった。けど買ってしまった)。
で、いつでも潰せるマシンに入れてみたのだが、数日後にはそいつのHDDを初期化する必要が出てしまい、ちょっとだけ遊んだHotCafe共々消えてしまった……。

結局、自宅のマシンには未だ躊躇してて入れていない。それというのもLCC-Win32を見付けたからだ。
GCCのページからたどれる。最初は何だろうかと思ったけど、freeなWin32のC Compiler処理系だった。

長所:
  • 高速。ちょっとセコイことをしてるけど、コンパイルは確かに速い
  • Direct-Xのサンプル付き。GUIもConsoleもどっちも作成可能。おまけに.dllも作成可能。(16bitアプリは駄目。C++もサポートしない。あくまでANSI-C準拠)
  • コマンドラインコンパイラだけでなく、統合環境付き。もちろんリソースエディタ込みでWin32ヘッダもライブラリも込みでlhaすると1.44MB FDに納まるという事実、信じられる?VC++はもとより、gccの現状から考えても冗談としか思えない。けどマジ。LibrettoでWin32アプリをコンパイルする、という条件を考えたらもう狂喜乱舞
  • gcc-win32のヘッダファイルで欠落している関数もちゃんとある。VC++依存のShift-JIS関係の関数までヘッダにあったのにはびっくりした。もっとも、完全な日本語化がなされている訳ではなくて、多分Windowsとの互換性を追求した結果なのだろう。#pragma関係でVC++依存なものもサポートしてるし(とはいえ、さすがに.VxDを作ることはできないようだ)
  • 作者はドキュメントで最適化は未だ未だと言っている。しかし、SDKのGenericをコンパイルする限り、VC++ 4.0より遥かに小さい.exeを作ってくれる(ただしgccが生成する.exeよりは大きい) VC++ 4.1/4.2/5.0は持ってないのでそれらとの比較はできません

    短所(注意点):
  • リンカが変。リンクエラーしても.exeを生成してしまうから、ぼーっとしててうっかりそいつを実行すると泣きを見る
  • 統合環境に癖がある。デフォルトのキーバインドとかフォントとか……。再設定をしても何か言うことを聞いてくれない所があったりする
  • DBCS非対応。そのままでは漢字文字列でコンパイルエラーを起こす。ピンと来た人、そう。「表」とかね。これに付いては作者に報告し「lex.cをいじってみて」ということで付属のソースを変更したのをメールしたから次バージョンでは何とかなってるかも
  • リソースコンパイラが不完全。作者からメールしてもらった最新版でも未だ完全ではない。Generic.rc程度ならちゃんと.resになるけど、SDKコンパチとはとても言えない
  • ヘッダに欠落がまだある。コンパイルエラーの時はSDKのヘッダと比較して修正の必要がある
  • ソース最終行は改行だけで終わらねばならない。つまりCR, LFが行末にないと行を認識しないのだ。
  • Windowsディレクトリにwinedit.iniを作るが、その説明がドキュメントにない。この点は次期バージョンで改修される模様

    で、取り敢えずここを直せば良いです:
  • GetProcessShutdownParameters()の定義をwin.h.に追加。(SDKではGetProcessVersion()の定義がGetProcessShutdownParameters()の次にあるので、そこに挿入するのが吉と思う)。内容は:DWORD STDCALL GetProcessVersion(DWORD);だね
  • #include <winver.h>をwindows.hに追加。SDKではそうなっているので
  • lex.cは次のように変更
    lex.c: line 474
            case '¥'': case '"': {
                static char cbuf[BUFSIZE+1];
                char *s = cbuf;
                int nbad = 0;
                *s++ = *--cp;
                do {
                    cp++;
                    while (*cp != cbuf[0]) {
                        int c;
                        if (map[*cp]&NEWLINE) {
                            if (cp < limit)
                                break;
                            cp++;
                            nextline();
                            if (cp == limit)
                                break;
                            continue;
                        }
                        c = *cp++;
    #ifdef JAPAN        // DBCS (Shift-JIS) trap
                        if (((0x80 < c) && (c <= 0x9f)) || ((0xe0 <= c) && (c <= 0xff))) {
                            if (s < &cbuf[sizeof cbuf] - 3) {
                                *s++ = (char)c;
                                c = *cp++;
                                *s++ = (char)c;
                                continue;
                            }
                        }
    #endif
    な、とこかな?