【PL/I学習|実務向け】PL/Iにおける「引数なし戻り値(RETURNS属性)」の重要性と実装の勘所

1. 導入:なぜ「RETURNS」の明示が重要なのか

メインフレーム開発の現場において、PL/Iのプロシージャ定義は非常に柔軟です。しかし、その柔軟さゆえに「変数参照」と「関数呼び出し」の区別が曖昧になり、意図しないバグを招くことがあります。特に、引数を取らない関数を呼び出す際、`RETURNS`属性を適切に指定しないと、コンパイラはそれを関数として正しく認識できず、期待した戻り値が得られません。本記事では、副作用を伴う状態取得関数を正しく実装・管理するための技術Tipsを解説します。

2. 基礎知識:関数と変数の境界線

PL/Iでは、プロシージャを呼び出す際に引数が不要な場合、括弧を省略して記述することが可能です。これが「変数参照」と「関数呼び出し」の混同を招く要因となります。
`RETURNS`属性は、コンパイラに対して「この識別子は計算の結果を返す関数である」というシグナルを送る役割を果たします。これがない場合、コンパイラは当該シンボルをメモリ上の変数として扱おうとし、結果として未初期化のデータや古い値を読み込んでしまうリスクがあります。

3. 実装・解決策:ENTRY宣言の徹底

関数を利用する側(呼び出し元)と定義する側の両方で、`RETURNS`属性を正確に宣言することが鉄則です。これにより、コンパイラは式の評価時に即座にプロシージャ呼び出しのコードを生成できるようになります。

4. サンプルプログラム

以下は、シーケンス番号を取得するような「状態取得関数」の実装例です。呼び出し側での宣言方法に注目してください。

/ — 呼び出し側のサンプル — /
/ 戻り値の型を明示的に指定することで、コンパイラに関数呼び出しであることを教える /
DCL GET_NEXT_SEQ ENTRY RETURNS(FIXED BIN(31));

DCL CURRENT_VAL FIXED BIN(31);

/ 関数呼び出し:括弧を省略しても、RETURNS宣言があるため正しく認識される /
CURRENT_VAL = GET_NEXT_SEQ;

/ — 関数側の定義サンプル — /
GET_NEXT_SEQ: PROC RETURNS(FIXED BIN(31));
DCL SEQ_STATIC FIXED BIN(31) STATIC INIT(0);

/ 内部状態を更新して返す(副作用のある関数の例) /
SEQ_STATIC = SEQ_STATIC + 1;
RETURN(SEQ_STATIC);
END GET_NEXT_SEQ;

5. 応用・注意点:現場でのトラブル回避

副作用への警戒:ゲッターとして実装した関数が、内部で静的変数(STATIC)を更新している場合、その呼び出しは「値の取得」以上の意味を持ちます。デバッグ時に「変数を参照しているだけだと思っていたら、実は値がインクリメントされていた」という事象が発生しがちです。

コード解析時の注意:古いソースコードを保守する際、`DCL`宣言が抜けていると、コンパイラはデフォルトの型(Contextual Declaration)を適用しようとします。これにより、予期せぬ型変換が発生したり、コンパイルエラーが抑制されて実行時に異常終了したりするケースがあります。

まとめ:引数なしの関数であっても、`RETURNS`属性は必ず明示してください。「記述しなくても動く」からといって省略するのは、将来的な保守性を損なう原因になります。型定義と属性の明示こそが、堅牢なメインフレーム資産を守るための第一歩です。

コメント

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