【実務・中級編】CICS環境におけるEXEC CICS READ/WRITEとPL/I構造体のマッピング – PL/Iの基本構文とデータ制御実践ガイド

【メインフレーム道】CICSとPL/Iの危険な関係:COMMAREAとBased変数アライメントの罠

若手諸君、お疲れ様。今日もバッチの Abend ダンプと格闘しているか?

PL/Iという言語の懐の深さに魅了されている一方で、その自由度の高さゆえに、一度踏み外すと「なぜ動くのかわからない」という迷宮に迷い込むのがこの世界だ。特にCICS環境下でのデータ受け渡し、すなわち`DFHCOMMAREA`とPL/I構造体のマッピングは、現場のエンジニアが必ず一度は血を見るポイントだ。

今日は、なぜか動かない、あるいは時折データが化けるという「見えない敵」の正体、「境界整列(アライメント)」について語ろう。

1. 予約語なきPL/Iの自由度と、その代償

PL/Iの最大の特徴は「予約語」が存在しないことだ。`IF`という変数名すら許される。これは柔軟性の裏返しだが、コンパイラにとっては「文脈を解析する」という重い負荷を強いている。

CICS通信領域(COMMAREA)を扱う際、我々はよく`BASED`変数を使って領域をマッピングする。だが、ここで初心者がやりがちなミスが、構造体のメンバーを単に並べるだけで満足してしまうことだ。

2. なぜ、アライメントが重要なのか?

CICSから渡される`DFHCOMMAREA`は、CICSが管理する純粋なメモリ空間だ。一方、PL/Iの構造体は、デフォルトではコンパイラが「計算機が最もアクセスしやすい境界(境界整列)」にデータを配置しようとする。

もし、構造体定義に何の指示も出さなければ、コンパイラは勝手にメンバ間に「パディング(詰め物)」を挿入する。結果として、CICS側の定義(COBOLでいう`PIC X(n)`の連続)と、PL/I側の構造体レイアウトが物理的にズレる。これがデータ化けの元凶だ。

3. 実践コード:ALIGNEDとUNALIGNEDを使い分ける

CICSマッピングにおいて、我々が絶対的に信頼すべきキーワードは `UNALIGNED` だ。これを使うことで、コンパイラに「余計なパディングを入れるな、詰めて配置しろ」と指示できる。

以下に、実務で使える定石コードを示す。

/i
/ ———————————————————– /
/ CICS通信領域(COMMAREA)のマッピング用構造体定義 /
/ ———————————————————– /
DCL 1 COMMAREA_LAYOUT BASED(DFHEIPTR),
3 TRANS_ID CHAR(4) UNALIGNED, / トランザクションID /
3 USER_KEY FIXED BIN(15) UNALIGNED, / 2バイトの整数 /
3 DATA_LEN FIXED BIN(31) UNALIGNED, / 4バイトの整数 /
3 MSG_BODY CHAR(100) UNALIGNED; / メッセージ本体 /

/ ———————————————————– /
/ CICS通信処理の典型的なフロー /
/ ———————————————————– /
EXEC CICS READ INTO(DFHCOMMAREA)
LENGTH(COMMAREA_LENGTH)
RIDFLD(USER_ID);

/ 構造体ポインタを通信領域の先頭アドレスに設定 /
DFHEIPTR = ADDR(DFHCOMMAREA);

/ ONユニットで異常系をハンドリングするのは基本中の基本 /
ON ENDFILE(VSAM_FILE) BEGIN;
PUT SKIP LIST(‘データが見つかりません’);
END;

/ データの参照例 /
IF TRANS_ID = ‘ABCD’ THEN DO;
/ 構造体のメンバに対して安全にアクセス可能 /
CALL PROCESS_DATA(MSG_BODY);
END;

4. 現場で生き残るための「鉄則」

コードを見て気づいたか? ポイントは以下の3点だ。

1. `UNALIGNED` を徹底せよ
構造体の宣言には、必ず`UNALIGNED`属性を付与すること。これを忘れると、`FIXED BIN(31)`の前後でコンパイラが勝手にアライメント調整を行い、後続のデータが数バイト後ろにズレる。
2. `BASED` 変数と `ADDR` の活用
`DFHEIPTR`(CICSが提供するポインタ)を`BASED`変数にセットすることで、メモリ領域を直接PL/Iのデータ型として解釈させる。これにより、いちいち`SUBSTR`関数で切り出すような泥臭いコーディングから解放される。
3. ONユニットで制御フローを制御せよ
CICSの`EXEC CICS`でエラーが発生した場合、単に`IF`文で分岐するのではなく、`ON CONDITION`や`ON ERROR`を適切に配置すること。特にメインフレームのバッチ処理では、予期せぬ異常終了時にどれだけ正確なデバッグ情報を吐き出させるかが、アーキテクトの腕の見せ所だ。

最後に

PL/Iは古い言語と言われるが、これほど厳密にメモリレイアウトを制御できる言語はそう多くない。アライメントを意識できるようになったとき、君はもう「動くコードを書くエンジニア」から「システムを設計するエンジニア」へ脱皮しているはずだ。

もし、それでもデータが化けるなら、それはコンパイラのオプション(`LIMIT`や`ALIGN`)が環境標準と食い違っている可能性がある。コンパイルリストの「Attribute and Cross-Reference Table」を読み解く癖をつけておけ。

健闘を祈る。また何かあればいつでも聞きに来い。

タイトルとURLをコピーしました