我正在修改这个高度关键的RPGLE程序,其中的更改涉及添加一个新的入口参数。
*entry plist
parm ecorp corp
parm edivi divi
parm eplvl parent lv
parm ewrsc wc rscd
parm eplnt plnt
parm eclvl child lv
parm emord ord
parm easst asst
parm emrwk mrwk#
parm eseqn seq #
parm easeq alt seq #
parm epprd alt seq #
parm eotst alt seq #
parm ewpqt alt seq #
parm ecmpc alt seq #
parm ewurs alt seq #
parm emurs alt seq #
parm epcdt alt seq #
parm E_Optn option
parm eeoj end of job
parm E_Pgm program
parm E_GRP MO GROUP
程序入口参数列表如上所述,除了我现在添加的最后一个参数。这个程序运行良好。但我有点担心的是,这是否会以某种方式影响这个项目的其他领域。即未传递最后一个输入参数的调用程序。
这个新的入口参数将只从作为更改一部分的另一个程序传递。还有相当多的其他程序将调用传递与前面相同参数列表的程序。
If (%Addr(E_Grp) <> *NULL);
Chain (E_Grp:EWURS:ssmurs) MFMPP00;
If %Found();
MchAllotted = *On;
Leave;
EndIf;
EndIf;
上面显示了代码中唯一使用此参数的其他区域。在这里,我已经确保在引用参数之前,检查参数是否已传递。
我已经测试过了,效果很好。然而,考虑到应用程序的关键性,仍考虑寻求专家帮助。
欢迎对此提出任何指导/建议。
您有内存损坏错误等待发生。。。
如果你试着在没有最后一个参数的情况下调用程序,并且它似乎起了作用,那么你很幸运,内存区域没有被使用。。。因此为零,并且您的%Addr(E_Grp) <> *NULL
按预期工作。
为了进行比较%Addr(E_Grp) <> *NULL
,调用程序必须传递该参数的*OMIT
特殊值。显然,这需要更改所有调用程序。
您想要的是不必更改调用程序,因此在被调用程序中需要的是参数为*NOPASS
。
您应该转换到被调用的程序以使用PR/PI而不是*ENTRY PLIST。然后您可以将最后一个参数标记为options(*NOPASS *OMIT)
然后在调用的程序中,您可以检查
- 如果参数被传递
- 如果传递的parm为NULL(*OMIT(
编码
// check if the parm was passed
if %parms() > = %parmnum(E_GRP);
// check if passed parm is not NULL
if %Addr(E_Grp) <> *NULL;
//ok to use E_Grp
Chain (E_Grp:EWURS:ssmurs) MFMPP00;
If %Found();
MchAllotted = *On;
Leave;
endif;
endif;
endif;
据我所知,RPG将调用方的参数视为"Do what you want"。意味着如果PGM01由PGM02调用,其中PGM1接受3个参数,PGM2用3个参数调用,则一切正常。当PGM01想要3个参数,而PGM02给出2个参数时,您可以这样做。但是,如果第三个参数是*NULL(就像您所做的那样(,您必须注意会发生什么。如果您用4个参数调用PGM01,而PGM01只"想要"3个,则没有问题,因为PGM01并不关心这一点。
但我会放弃*ENTRY风格,转而使用原型。在那里你可以定义,如果一个参数是可省略的,那么该参数可以使用,但不必使用。请阅读D-Spec
和PR
关键字的手册。
如果不打算在程序中修改参数,那么使用它的更安全的方法是将变量初始化为默认值,如果传递了参数,则将参数复制到该变量。这样,如果添加更多使用参数值的代码,他们就不必记住添加检查。
... Change the name of E_GRP parameter to E_GRP_parm
dcl-s E_GRP ... INZ(whatever);
if %parms() >= %parmnum(E_GRP_parm);
E_GRP = E_GRP_parm;
endif;
您也可以将此技术与被更改的参数一起使用:
dcl-pi *n;
something_parm char(10) OPTIONS(*NOPASS);
end-pi;
dcl-s something char(10) INZ('Whatever');
// Get the value of the "someThing" parameter if it was passed
if %parms() >= %parmnum(something_parm);
someThing = someThing_parm;
endif;
...
// Update the "someThing" parameter if it was passed
if %parms() >= %parmnum(someThing_parm);
someThing_parm = someThing;
endif;