- PR -

1.3→1.4へアップグレードしたらコンパイル通らなくなった

投稿者投稿内容
ぴろ
会議室デビュー日: 2003/08/19
投稿数: 5
投稿日時: 2003-08-20 15:26
わらびさん、お犬様さんレスありがとうございます。

JAVAのnative2ascii(Unicode以外のソースをUnicodeに変換するツール)を
それぞれ1.3.1,1.4.1でかけた所下記のような結果になりました。
お犬様さんに教えていただいたように、1.4.1環境では1バイト文字として
解釈されて2文字に変換されてしまうのがコンパイルエラーの原因だとわか
りました。

***** 元のコード *****
if ( ( '' <= buf[i] && buf[i] <= '' )

***** JDK1.3 : native2ascii -encoding SJIS 結果
if ( ( '\ufffd' <= buf[i] && buf[i] <= '\ufffd' )

***** JDK1.4 : native2ascii -encoding SJIS 結果
if ( ( '\ufffdK' <= buf[i] && buf[i] <= '\ufffd\ufffd' )

(なんで余分な「K」や「\ufffd」がついてしまっているのか
わからないんですが・・・。今いろいろ調べてるんですが、
ご存知の方いらっしゃいますか?)

このnative2asciiの実行結果の差異の原因がyuzyさんや米山@クロノスさんに
教えていたいたリンクの内容にある「Shift_JISのエイリアスの変更」というこ
となのでしょうか。
リンク内容にある、「Shift_JIS」を利用した場合ならばエイリアス変更により
 1.3.1 → MS932
 1.4.1 → SJIS
となるのはわかるのですが、今回は1.3.1でも1.4.1でも
「Shift_JIS」は利用せず、「SJIS」をエンコーディングに指定しているので
上記マッピングの違いはとくにコンパイルエラーの原因に
なっているとはあまり考えていませんでした。
どこか根本的に勘違いしてますでしょうか。。。
お犬様
ベテラン
会議室デビュー日: 2003/01/26
投稿数: 67
投稿日時: 2003-08-20 18:33
引用:
ぴろさんの書き込み (2003-08-20 15:26) より:

(なんで余分な「K」や「\ufffd」がついてしまっているのかわからないんですが・・・。今いろいろ調べてるんですが、ご存知の方いらっしゃいますか?)


ご存知かもしれませんが、\uFFFD の説明から。
引用:
http://www.unicode.org/charts/PDF/UFFF0.pdf

FFFD REPLACEMENT CHARACTER
used to replace an incoming character whose value is unknown or unrepresentable in Unicode (未知もしくは Unicode で表現できない文字が入力された場合に、置き換えて使用する)


ソースを調べたわけではないですが、おそらく以下のような感じで処理されたのだろうと思います。
  • : 0xFC4B
    • jdk13:
      -> 0xFC は 0x81-9F、0xE0-FC の範囲内なので 2バイト文字の先頭と判定
      -> 0xFC4B は SJIS には無い文字
      -> 未知の文字 0xFC4B を \uFFFD で置換。
       出力 : \uFFFD

    • jdk14:
      -> 0xFC4B は SJIS には無い文字なので、0xFC は2バイト文字の先頭で無いと判定
      -> 未知の文字 0xFC を \uFFFD で置換
      -> 4B は 'K' なので \u004B として処理。
       出力 : \uFFFD \u004B


  • : 0x878F
    • jdk13:
      -> 0x87 は 0x81-9F、0xE0-FC の範囲内なので2バイト文字の先頭と判定
      -> 0x878F は SJIS には無い文字
      -> 未知の文字 0x878F を \uFFFD で置換。
       出力 : \uFFFD

    • jdk14:
      -> 0x878F は SJIS には無い文字なので、0x87 は2バイト文字の先頭で無いと判定
      -> 未知の文字 0x87 を \uFFFD で置換
      -> 0x8F27 (0x27 は盾フ直後の「'」) は SJIS には無い文字なので、0x8F は2バイト文字の先頭で無いと判定
      -> 未知の文字 0x8F を \uFFFD で置換
       出力 : \uFFFD \uFFFD


[ メッセージ編集済み 編集者: お犬様 編集日時 2003-08-20 18:36 ]
ふうた
大ベテラン
会議室デビュー日: 2001/08/23
投稿数: 198
お住まい・勤務地: 岡山
投稿日時: 2003-08-20 23:15
#ちょっと視点を変えて

今回の検証によって、JDK1.3.1の場合も

***** 元のコード *****
if ( ( '' <= buf[i] && buf[i] <= '' )

に対して、

***** 実行時の処理と等価のコード *****
if ( '\ufffd' == buf[i] )

と同じ処理しかできていなかったことにならないでしょうか?


もともとのコードの詳細な意図が分からないですが、たまたま期待したアウトプットにほぼ近い結果が得られていただけで、作者が本当に意図していた処理はできていなかったように見えます。

この際ですから、もともとの意図を再考してコードの見直しを行ってみてはどうでしょう?



[ メッセージ編集済み 編集者: ふうた 編集日時 2003-08-20 23:17 ]
ぴろ
会議室デビュー日: 2003/08/19
投稿数: 5
投稿日時: 2003-08-21 10:27
皆様、レスありがとうございます。

文字コードやバージョンによる違いなど
大変勉強になりました。

私は今まで文字コードの問題は結構避けがちに
なっていたのですが、今回皆さんにお伺いして
今まで抱いていた疑問が少しずつ解けていった
ように思います。

どうもありがとうございました。m(__)m
さる
会議室デビュー日: 2003/08/29
投稿数: 3
投稿日時: 2003-08-29 17:09
はじめまして。

ぴろさんの問題は解決されたようですが、この問題は仕様の問題なのでしょうか。
SUNのJDKで1.4.0から1.4.1のタイミングでこの挙動が変わったのは知っていたのですが
これは
Javaの仕様としての変更
SUNの実装の変更
バグ
のどれなのでしょうか。
ご存知の方がいらしたらご教授願います。

スキルアップ/キャリアアップ(JOB@IT)