Delphiで作った大昔のプログラムをメンテナンスしている。Delphi 2009以降とそれより前では、文字列周りの仕様が激変していて、それが移行の障害となっているのだが、またもや新たな障害が出てきた。
その、CharとStringにまつわる話は、以前に書いてみた。
CharはAnsiCharに、StringはAnsiStringに、という話なのだが、関数周りでも気が抜けないようだ。
Ordinal数、すなわち順序数を受けてChar型の文字を返すChr関数。Delphi 2009より前では普通に使ってきたが、これをDelphi 2009以降で使うと予期せぬ挙動に戸惑うことになる。
Delphi 2009より前では、0〜255の文字コードを受けて、それをChar型の値として返す単純なものだった。何のために存在?というと、それはChr型を必要とするコンテキストのためさ、としか言いようがなかった。
しかし、引数に与えられたOrdinal数が、128以上ならどうなるか?そこはASCIIでは規定されていないので、Delphi 2009以降ではUnicodeとしてのChar型が返されるのだ。
例えば、文字コード177(B1)は、半角カタカナの「ア」だ。これをChr関数に渡すと、Unicodeの177が返されるが、それは「±」だ。世界レベルで見れば、半角カタカナなどと言うのはあり得ないのだろう。
この問題を解決するには、Chr関数を使わなければよいという、単純な解。AnsiString型の変数に代入するとかする際に、単純にキャストすればいい。
str := str + AnsiChar( wc );
ここで、wcはOrdinal数、strはAnsiString型である。これで、wcが問題なくAnsiChar型と認識され、それに基づいてstrに加算される。
ほとんどの人には関係ないようなテーマだが、ほかにもはまっている人がいるかも?という思いで投稿にさせてもらった。