1. 導入:なぜRETURNS属性が必要なのか
メインフレームのPL/I開発において、「サブルーチン(CALL)」と「関数(Function)」を明確に使い分けることは、読みやすく保守性の高いコードを書くための第一歩です。特に、計算結果などを式の中で直接使いたい場合、プロシージャに「戻り値があること」をコンパイラに正しく伝える必要があります。そのために必須となるのがRETURNS属性です。これを省略すると、コンパイラは戻り値を正しく認識できず、予期せぬ実行時エラーや計算ミスを引き起こす原因となります。
2. 基礎知識:プロシージャと戻り値の仕組み
PL/Iでは、処理のまとまりを「プロシージャ(PROC)」と呼びます。
・CALL文で呼び出すプロシージャ:戻り値を返さない(または明示的に返さない)処理の塊。
・関数(Function):計算結果や状態を呼び出し元に返す処理。
RETURNS属性は、この「関数」を作成する際に、「何を、どのような形式で返すか」をコンパイラに宣言するものです。内部的には、戻り値はCPUのレジスタ(主にR15)に格納されて呼び出し元に渡されます。この定義がないと、呼び出し元は「戻り値があるはずなのに受け取れない」という状態になってしまいます。
3. 実装と解決策:RETURNS属性の記述法
関数を定義する際は、PROCステートメントの末尾に「RETURNS(型)」を記述します。型には、数値ならFIXED DEC(15,2)など、文字ならCHAR(10)などを指定します。また、プロシージャの内部では必ず「RETURN(値);」ステートメントを使用して値を返す必要があります。
4. サンプルプログラム
以下のコードは、2つの数値を加算して結果を返す単純な関数例です。そのままコピーしてコンパイル環境で試してみてください。
/ メインプログラムから呼び出される関数定義 /
CALC_SUM: PROC(P_VAL1, P_VAL2) RETURNS(FIXED DEC(10,0));
/ 引数の宣言 /
DCL P_VAL1 FIXED DEC(10,0);
DCL P_VAL2 FIXED DEC(10,0);
/ 計算結果を戻り値として返す /
/ RETURNS属性で指定した型と一致させること /
RETURN(P_VAL1 + P_VAL2);
END CALC_SUM;
/ 呼び出し側のイメージ /
/ DCL TOTAL FIXED DEC(10,0); /
/ TOTAL = CALC_SUM(100, 200); /
5. 応用・注意点:現場で陥りやすいバグの回避
現場でよくあるミスは、「RETURNS属性の型」と「RETURN文で返す値の型」の不一致です。例えば、RETURNS(FIXED BIN)と宣言しているのに、文字列を返そうとするとコンパイルエラーや予期せぬデータ変換が発生します。
また、既存の古いコードを調査する際、RETURNS属性が付いていないプロシージャを関数として呼び出そうとしていないか注意してください。もし「戻り値を受け取りたい」という要件があるなら、そのプロシージャ定義にRETURNS属性を追加し、戻り値の型を適切に定義し直す必要があります。現代の言語における「型付き関数」の考え方をPL/Iでも意識することが、堅牢なシステム構築の鍵となります。

コメント