Tagged: VC++

最近、Windows標準のShift-JISから、Web標準となっている(?)UTF-8への文字コード変換が必要な場合がちらほら出てきている。

マルチプラットフォームでデータをやり取りする場合なんかでもUTF-8が結構使われていたりする。

こういうコード変換なんかは、テキストエディタ等を使えば、簡単に変換できる。
最近ではメモ帳でもUTF-8保存ができるようになったし。

でも、このコード変換が100個、1000個、と数が増えてくると手作業は無理。

そんな訳で、VC++(非.NET)でSJISからUTF-8に変換するプログラムを作ってみることにした。
# バッチで利用したいという理由もあったんで。

しかし、SJISからUTF-8に直接変換するようなWin32APIは用意されていないことに気付いた。
C#やVB.NETならきっと一発で変換できるんだろうけど(多分)。

調べてみると、シフトJISからUTF-8に変換するためには、一回Unicodeに変換させる必要があることが分かった。
あぁ面倒。

まず、MultiByteToWideCharを使用し、SJISからUnicodeへ。
次に、WideCharToMultiByteを使用し、UnicodeからUTF-8へ。

出来上がったプログラムソースは以下のとおり。
(さらに…)

前に、とある処理でこんなコーディングをしたことがあった。

// 別スレッド
UINT sampleThread(LPVOID pParam)
{
  CSampleDlg* pDlg = (CSampleDlg*)pParam;
  for( ; 0<pWait ; pWait--){
    // ループ内の処理
  }
  :
}

しかし、これが何故か無限ループに陥ってしまう。
同様のミニプログラムを作成しても再現しない。
なぜか、これを使用している某プログラムのみ発生する。

でも、デバッグモードでは問題なく動作する。

う~ん、怪しい。
試しにこのスレッド処理だけをコンパイラの最適化を無効にしてみた。

// 別スレッド
#pragma optimize( "g", off )
UINT sampleThread(LPVOID pParam)
{
  CSampleDlg* pDlg = (CSampleDlg*)pParam;
  for( ; 0<pWait ; pWait--){
    // ループ内の処理
  }
  :
}
#pragma optimize( "g", on )

すると動くではないか。。。

最適化によってコードのサイズを小さくし実行速度を向上しているようですが、
たまに、こういった不具合にも突き当たります。
# 不具合というか仕様なんでしょうけど。

前に、最適化有無によって倍精度浮動小数点の演算結果(べき乗)が異なるって問題にもぶち当たったことがあったけど、これも最適化有無によるものでした。
浮動小数点の値自体、もともと誤差を含んでいるので、どちらも正しい値なんですが。。。

ちなみに、あとから分かったことは、

for( ; 0<pWait ; pWait--){

for(wkWait=pWait ; 0<wkWait ; wkWait--){

に変更するだけで問題は解決しました。

よく上級の人のソースや、本で、

for(;;)

なんて書き方も紹介してますが、あまり懲りすぎると痛い目にあいます。
特に、複数人で開発している製品なんかは、他人にも分かりやすいコーディングをしなければ、バグ作り込みの原因にも成りかねません。
あまり、性能に影響が無い部分は、なるべく見やすい一般的なコーディングをした
方がよいのでしょう。