OS V5R4M0 からは CALLPROC
(プロシージャー呼び出し) のパラメータのキーワードには
パラメータの受け渡し方法が指定できるようになっている。
省略値は *BYREF
であるが、 *BYVAL
を指定することもできる。
一体、この *BYREF
や *BYVAL
とは何であろうかと疑問に思う諸氏も少なくないと思う。
そこでこの *BYREF
と *BYVAL
の意味と CLP の変数の意味を考えて頂く機会として
解説を行いたい。
DCL VAR(&DATA) TYPE(*CHAR) LEN(1280) DCL VAR(&OPT) TYPE(*CHAR) LEN(4) + VALUE(X'00000001') /* EBCDIC */ : CALLPRC PRC(RPGSEND) PARM((&DATA *BYREF) (&OPT + *BYVAL) (960))
Visual BASIC でも *BYREF
や *BYVAL
の指定があるように、
*BYREF
............... 参照照会、つまりポインター渡しであることを意味する。*BYVAL
............... 値渡し、つまり値を直接、渡すことを意味する。である。
簡単に言えば、*BYREF
はポインター値がパラメータであり、*BYVAL
は変数値がパラメータである。
上記の例であれば呼び出されるプロシージャー: RPGSEND
は次のように定義されている。
1765.00 /***********************************************/ 1766.00 int RPGSEND(char* sndbuf, int opt, int sndlen) 1767.00 /***********************************************/ 1768.00 /* opt : 1= EBCDIC, 2= ASCII */ 1769.00 { : : 1818.00 return TRUE; 1819.00 }
ご覧のように RPGSEND
プロシージャーは C言語のソースであり、
第一パラメータは char* sndbuf
という文字ポインターである。
第二パラメータは int opt
という integer
の整数値パラメータである。
従って
CALLPRC PRC(RPGSEND) PARM((&DATA *BYREF) (&OPT + *BYVAL) (960))
とは第一パラメータは文字ポインターであるため、ポインターを示す *BYREF
を使って
記述されているし、第二パラメータは整数値であるため *BYVAL
を使って *BYVAL
によって
記述されているのである。
ところで CALLPRC
コマンドの省略時の値は *BYREF
である。
つまりポインター渡しが省略値なのである。
OS V5R4M0 以前は *BYREF/*BYVAL
の区別もなかったのであるから、それまでも
*BYREF
としてパラメータ値が渡されていたことになる。
RPG 開発者はよもやポインターを渡していたとは思わなかったであろう。
そのまま CLP の変数を渡すことはポインター値を渡していることになっていたのである。
もっと言えば、
CLP から RPG (=ILE-RPGも含む) や COBOL に渡してしたパラメータは
これまで、すべてポインター渡しであった。
ということが言えるのである。
RPG の開発者なら CLP から受取ったパラメータの値を呼び出された側の
RPG のプログラムの中で値を変更して呼び出し側の CLP に戻すと
そのパラメータ値が変更されることは誰でも知っていると思う。
一般に汎用的な関数で値を受け取って、そのパラメータ値を変更して元の
呼び出し側に戻ってもパラメータ値が変更されることは、ない。
RPGでパラメータ値を変更することができるのはポインター渡しで
渡しているからに他ならない。
他の C, Java, BASIC などでこのような例はない。
IBM がパラメータ渡しを基本として RPG を設計したのは、そのほうがIBM ユーザーにとって
わかりやすい、と判断したからであろう。
私たちは知らないうちにポインター渡しを使っていたのである。
ひとつ内部的な理解を頂けたかと思う。