C/400

49. C/400 のOS Ver6.1 への対応とは ?

System i OS Ver6.1 では実行時の動作がかなり厳しくなっており、
特に C/400 の場合はコンパイルは成功してオブジェクトが生成されたとしても
実行時に動作が不安定になって、それまでのリリースとは違って、正しく動作しなくなる。
問題になるのは次の使用方法である。
良く注意して次のC/400ソースを眺めて頂きたい。

char user[10], password[10];

memset(user, 0, sizeof(user));
strcpy(user, USER);
user[10] = 0x00;

一見、正しいようにも思えるこのソースであるが、問題は

user[10] = 0x00;

の部分である。
System i の開発者はユーザー名は 10 バイトであるのをよく承知しているので
ユーザー名の定義として、

char user[10];

のように 10バイトを定義しがちであるが、ここまでは正しいとしても
user[10] = 0x00; の 10 の数字は 11 バイト目に NULL ( 0x00 ) を入れる
演算になってしまう。
旧リリースでは、この誤った記述はOS によって無視されて実行時には問題にはならない。
しかし Ver6.1 ではより厳しくなって user[10] = 0x00; の演算命令に対して
コンパイル時点で警告メッセージが報告される。

しかしコンパイルは正常に完了してオブジェクトも生成されるのでこの警告メッセージは
見落とされがちである。
次に実行してみると user[10] = 0x00; の演算によって次に定義されている password の
最初の1桁目が 0x00 として破壊されてしまうことになる。
これでは期待した通りに動作しないのも無理はない。
System i のフィールド名やファイル名, ... に良くなじんでいる長さ + 1 バイトを追加して
NULL-STOP の 1 バイト分を確保しておかないと、すべてのシステムで一斉に誤動作を
起こしてしまうのである。
これは STROBJCVN で変換しても同じことが発生する。
海外ソフトウェア製品のほとんどが何らかの形で C/400 が使用されているので
Ver6.1 対応と保証されていない製品に関しては慎重な移行の確認が必要となってくる。

既に IBM は 2010/1/5 日で V5R4M0 の出荷を終了すると公示しているので
今後は Ver6.1 が主流になるのはまちがいない話である。