我正在修改这个非常关键的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;
上面显示了代码中使用此参数的唯一其他区域。在这里,我确保在引用参数之前,先检查是否已传递参数。
我已经测试过,可以正常工作。但是,考虑到应用程序的重要性,仍然认为寻求专家的帮助。
欢迎对此提供任何指导/建议。
答案 0 :(得分:5)
您有等待发生的内存损坏错误...
如果您尝试在不使用最后一个参数的情况下调用该程序,并且看起来似乎可行,那么您就很幸运,未使用该存储区...因此为零,而您的%Addr(E_Grp) <> *NULL
可以正常工作如预期的那样。
为进行比较%Addr(E_Grp) <> *NULL
,您的调用程序必须为该参数传递*OMIT
特殊值。显然,这需要更改所有调用程序。
您想要的是不必更改调用程序,因此在被调用程序中需要的是参数为*NOPASS
。
您应该转换为调用程序以使用PR / PI而不是* ENTRY PLIST。然后,您可以将最后一个参数标记为options(*NOPASS *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;
答案 1 :(得分:2)
据我所知,RPG正在考虑将来自调用方的参数视为“做您想做的事”。这意味着如果PGM02调用了PGM01,则PGM1接受3个参数,而PGM2调用3个参数,一切都很好。当PGM01需要3个参数而PGM02给2个参数时,您可以这样做。但是,您必须注意如果第三个参数为* NULL(会这样做)会发生什么。如果您使用4个参数调用PGM01,而PGM01仅“希望” 3,则没有问题,因为PGM01对此并不关心。
但是我会留下* ENTRY样式,而使用原型。您可以在此处定义是否可以省略参数,该参数可以使用,但不必使用。请阅读手册D-Spec
和关键字PR
。
答案 2 :(得分:2)
如果不打算在程序中修改参数,则使用它的更安全方法是将变量初始化为默认值,如果传递了参数,则将参数复制到该变量。这样,如果添加了更多使用参数值的代码,他们将不必记住添加检查。
... 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;