考慮事項

IBM® i のデフォルト環境は主として EBCDIC 環境であるため、アプリケーションで UTF サポートを使用する場合は、このトピックに記載されている状態について熟知しておく必要があります。

UTF サポートを使用してコンパイルしたモジュールと、UTF サポートを使用しないでコンパイルしたモジュールが、プログラムまたはサービス・プログラムに含まれている場合、予期しない不一致が起こらないように注意を払う必要があります。 ワイド文字とワイド文字ストリングのサイズは、非 UTF モジュールの場合は 2 バイトになり、UTF モジュールの場合には 4 バイトになります。 したがって、モジュール間でワイド文字を共用した場合、正常に処理されないおそれがあります。 ナロー (非ワイド) 文字および文字ストリングは、非 UTF モジュールの場合はジョブの CCSID で表記され、UTF モジュールの場合は CCSID 1208 で表記されます。 したがって、モジュール間でナロー文字を共用すると、いずれも正常に処理されないおそれがあります。

setlocale() を実行して、ロケールを別の CCSID に設定するときは、必ず標準出力ファイルをフラッシュして、複数の CCSID を含む文字データによるバッファリング問題を回避する必要があります。 stdout は、デフォルトではライン・バッファーであるため、各出力行が改行文字で終了すれば問題は発生しません。 しかし、そのようになっていない場合には、出力が意図どおりに表示されないおそれがあります。 この問題について、以下のサンプルで説明します。
#include <stdio>
#include <locale.h>

int main() {
   /* This string is in CCSID 1208 */
   printf("Hello World");

   /* Change locale to a CCSID 37 locale */
   setlocale(LC_ALL, "/QSYS.LIB/EN_US.LOCALE");
   #pragma convert(37)

   /* This string is in CCSID 37 */
   printf("Hello World\n");

   return 0;
}

この場合、最初の printf() により、CCSID 1208 のストリング "Hello World"stdout バッファーへコピーされます。 setlocale() が実行される前に、stdout がフラッシュされて、そのストリングが画面にコピーされます。 2 番目の printf() により、CCSID 37 のストリング "Hello World¥n"stdout バッファーへコピーされます。 末尾にある改行文字によって、バッファーはその時点でフラッシュされ、全バッファーが画面にコピーされます。 現行ロケールの CCSID は 37 であり、この画面で問題を起こすことなく CCSID 37 を処理できるため、全バッファーは変換なしでコピーされます。 CCSID 1208 の文字は、読めない文字として表示されます。 フラッシュが実行済みであれば、CCSID 1208 の文字が CCSID 37 に変換され、正常に表示されます。

ほぼすべてのランタイム関数は UTF をサポートするように変更されていますが、そうでない関数も若干存在します。例外処理を扱う関数および構造体 (_GetExcData() 関数、_EXCP_MSGID 変数、例外ハンドラー構造体 _INTRPT_Hndlr_Parms_T など) は、ランタイムではなく、オペレーティング・システムによって提供されます。これらは、完全に EBCDIC です。 getenv() 関数と putenv() 関数は、EBCDIC のみを処理します。 QXXCHGDA() 関数と QXXRTVDA() 関数は、EBCDIC のみを処理します。 argv パラメーターおよび envp パラメーターも、EBCDIC のみです。

レコード入出力関数 (つまり、_R で始まる関数) は、UTF を完全にサポートしているわけではありません。UTF をサポートしない関数には、_Rformat()_Rcommit()_Racquire()_Rrelease()_Rpgmdev()_Rindara()_Rdevatr() などがあります。UTF オプションによってコンパイルする際に、これらを使用することはできますが、受け付けおよび生成可能なものは EBCDIC のみになります。 さらに、_R 関数によって返される構造体内の文字データは、UTF ではなく EBCDIC となります。

他のオペレーティング・システム関数では、UTF をサポートするための変更は行われていません。例えば、open() などの統合ファイル・システム関数では、引き続きジョブの CCSID を使用できます。その他のオペレーティング・システム API でも、引き続きジョブの CCSID を使用できます。 UTF アプリケーションの場合、これらの関数に提供される文字および文字ストリングを、QTQCVRT、iconv()#pragma convert などの方法を使用して、ジョブの CCSID に変換する必要があります。