続C4819問題

今日はコンサートのため早めに更新。

コンパイラの動作

C4819問題を考える前に、コンパイラ(プリプロセッサも含む)がどのように動いているのか考えて見ます。コンパイラは次の3つの文字セットを使用します。(説明はいい加減です)

ソースファイルの物理的文字(physical source file characters)
ソースコードの文字そのもの(以下、物理ソース文字集合と呼ぶ)
基本ソース文字集合(basic source character set)
パーサーが使用する文字セット
実行文字集合(execution character set)
実行バイナリに埋め込まれる文字セット

これまでのマルチバイトベースのコンパイラの場合、
物理ソース = 基本ソース = 実行文字 = 環境依存のマルチバイト文字セット
で、文字コードの変換は必要なく、たとえShift-JISのソースにISO-8859-1が混じっても無理やりShift-JISと解釈すればよかったわけです。
ところが、VC8はUnicode(UTF16、UTF8)のソースコードを受け付けるようになりました。そのため、基本ソース文字集合Unicodeベースに置き換わったものと推測できます。そしてソースコードがマルチバイトの場合、Unicodeへの変換が必要になったのです。

どう対処すべきなのか

ソースコードにマルチバイト文字を使用する場合、実行文字集合が物理ソース文字集合と同じになるのは当然です。また、基本ソース文字集合Unicodeにすることも、ワイド文字(列)リテラルを考慮すると自然な流れです。となると、物理ソース文字集合コンパイラに指定する以外に道はありません。もちろん、ソースコードUnicodeの場合は実行文字集合を指定したいところです。
おそらく、MSの言い分は「Unicodeを使え!」なんでしょうが、、、。

他のコンパイラの実装

Borland C++には物理ソース文字集合のコードページを指定する「-CP」オプションがあります。実行文字集合も物理ソース文字集合と同じになります。