cpp_sj / cc1_sj 

cpp_sj113.lzh (gcc v2 用)
cc1_sj111.lzh (gcc v3 用)

 これらのプログラムは、 gcc(mingw) でコンパイルする c/c++ソースにシフトJIS(マルチバイト)文字を用いたい場合に 不具合となる \ コードを含む全角文字の対策をするもので、 gcc v2ならCプリプロセッサ(cpp)に、v3ならコンパイラ(cc1) にうわっかぶせ(ラップ)して用います。

※ gcc v4(?)以降の場合は TDM版 mingw を使えば、オプションに

--input-charset=cp932 --exec-charset=cp932
を指定することで、SJISソースを扱えるようです。




 mingw へのインストール方法 

 私が作業した mingwのgccバージョンは

gcc version 2.95.3-5
(gcc version 3.1.1)
で、バージョンが違うと色々(ディレクトリ構造など)の 状況が違うので、このプログラムが不要であったり不可の であったり、手直しが必要になるかもしれません。


 とりあえず、このバージョンで、 mingw のインストールしてあるディレクトリを

c:\mingw
とします。
 このとき
c:\mingw\lib\gcc-lib\mingw32\2.95.3-5
(v3なら c:\mingw\lib\gcc-lib\mingw32\3.1.1)
というディレクトリがあります。
(少しバージョンが違うと 2.95.3-5(3.1.1) の部分が違うでしょう)。
このディレクトリの中に
cpp0.exe
(v3なら cc1.exe cc1plus.exe cc1obj.exe)
という実行ファイルがあります。  このファイルをまず、
cpp0_org.exe
(cc1_org.exe cc1plus_org.exe cc1obj_org.exe)
に名前を変更し、次に、cpp_sj.exe (cc1_sj.exe) を
cpp0.exe
(cc1.exe cc1plus.exe cc1obj.exe)
の名でこのディレクトリにコピーします。 とりあえず、これでおわり。


 使い方 

 インストールがすんだ状態で、

> gcc -D_CPP_SJ tst.c
のように -D_CPP_SJ を指定することで、 シフトJIS文字の \ 対策したコンパイルが行えます。
指定のない限りは、元の動作のまま(変換無し)です。

 また、

 -D_CPP_SJ=0   未指定と一緒
 -D_CPP_SJ=1   -D_CPP_SJ のみと一緒
のようにも指定できます。 マクロ名 _CPP_SJ をソース中に 使う場合があるかな、と用意しましたが、基本的には、 -D_CPP_SJ の指定の有無のみでの運用を想定しています。


 \ を含むシフトJIS全角文字の問題 

 シフトJIS 全角文字に未対応のコンパイラで \を含む全角文字を 用いると

  1. コンパイルエラーになる
    ex) printf("表");
    ※ 右の" が表の下位 0x5C のため \" として、文字列が 継続していることになる

  2. 実行時に文字化けが発生する
    ex) printf("表示\n");
    ※ 右の" が表の下位 0x5C が消え1バイトづつづれて 強引に文字列が形成される

  3. ソースが一行コンパイルされない
    ex)
      //表
      a = a + 1;
    ※ 行末 \+改行は、行連結機能となるので、a=a+1; が コメント扱いになり、実行されない.
    (追記: #error メッセージ も同様の問題あり)
のような問題が起きます。

1. はコンパイル時にエラーが出て気づけますが、
2. は不正な文字コードに化ければ警告がでますが、 そうでなければ実行時まで見つかりませんし、
3. は、警告レベルを上げておけば

worning: multiline `//' comment
と出ますが、一見正しいソースですし行連結のことを知 らなかったり失念している人だとつい見過ごされやすい バグになります。
(シフトJIS/MS全角対応を謳ったコンパイラでも 枯れていないバージョンならば、 この手のことを疑ってかかったほうがよい場合もあるかもしれません)


 このプログラムでの \ 対策方法 

 C/C++ソース中で 0x??5C のような下位バイトが \ になる 全角文字の直後に \ を挿入することで対処しています。

 ただし例外として

  //表
  /*
   *ソ
   */
 のようにコメント中の問題の文字(表,ソ)の直後で改行が あった場合は、\の代わりに全角空白( )を挿入しています。 (不要なような気もしますが、流用ルーチン内を修正するのも 面倒なのでそのまま)


 gcc v3以降について 

 gcc v3 以降はどうも外部の cpp を呼ばないようになったので かわりに cc1 で対処する版を用意しました。

gcc v4以降については冒頭に追記したとおり TDM版 mingw を 使うのがよいでしょう。


 更新 

2004-01-17
cc1_sj> #include "..." (<...>でなく)に対応できていなかったので、 テンポラリをソースファイルと同じフォルダに作成するようにして、修正。
cc1_sj> エラー行番号がずれるので修正。
2010-03-07
tdm版mingwについて追記. リンク切れ(消失)したツールに関する記述を削除.


[back]