为什么我必须为主程序指定一个 ExtPgm 参数?
Why do I have to specify an ExtPgm parameter for the Main Procedure?
我的程序,PKGDAYMONR 有控制选项:
ctl-opt Main( CheckDailyPackages )
CheckDailyPackages 程序有以下 PI:
dcl-pi *n ExtPgm( 'PGMNAME' );
如您所见,ExtPgm
参数不是程序的名称。其实就是模板源里过来的,忘记改了。尽管 ExtPgm
中的名称错误,但程序运行没有问题。
如果我删除该参数并将关键字保留为 ExtPgm
,我会收到以下消息:
RNF3573: A parameter is required for the EXTPGM keyword when the
procedure name is longer than 10.
如果我完全从过程界面中删除 ExtPgm
,它也会抱怨:
RNF3834: EXTPGM must be specified on the prototype for the MAIN()
procedure.
如果我输入的值无关紧要,为什么我必须指定一个参数?
O/S级别:IBM i 7.2
可能值得 作为服务提供商的缺陷追究;大概对于大多数人来说,这将是 IBM 而不是第三方,因为他们无论如何都必须联系 IBM,因为他们认为问题显然出在他们的编译器上。除此之外,作为我的"Answer",我提出一些想法:
IMO,显然与 OP 一致,在给定场景中命名 ExtPgm 似乎毫无意义。我认为编译器在 混淆 时试图在 隐式生成的原型 的验证中强制执行某些要求,因为只有一个过程接口已提供;即强制执行适用于显式原型的要求,但在给定场景中可能被忽略的要求[因此不再是要求]。我建议虽然 RNF3573 似乎适合诊断显式原型的 EXTPGM 规范,但 IMO 同样的效果是不合适的 [即不应为编译器生成的隐式原型执行验证。
FWiW:是否测试了该自由格式代码的固定格式等效项,以查看是否产生了相同或不同的错误?以下源代码当前包含以 'PGMNAME' 作为参数的 EXTPGM 规范 [即提供 10 字节命名 的任何虚假值来请求编译器,就像在 OP 的场景中所做的那样,只是为了成功编译],但可以用对源进行更改的其他变体,模仿对自由形式变体所做的操作,以测试 same\consistent 验证和错误是否有效:
- 只是编码了 EXTPGM 关键字(w/out 参数);是RNF3573的效果吗?
- EXTPGM 关键字可以省略;是RNF3834的效果吗?
- 完全删除了 D-spec(如果没有定义参数);这不是 OP 中提到的正在尝试的变体之一,所以……效果?
H MAIN(CheckDailyPackages)
*--------------------------------------------------
* Program name: CheckDailyPackages (PGMNAME)
*--------------------------------------------------
P CheckDailyPackages...
P B
D PI EXTPGM('PGMNAME')
/free
// Work is done here
/end-free
P CheckDailyPackages...
P E
EXTPGM 关键字用于定义要原型化的程序的外部名称。如果你提到 EXTPGM 那么程序将被动态调用。
让我们举个例子来解释您的查询。
飞碟
D cmdExc PR ExtPgm('QSYS/QCMDEXC')
D 200A const
D 15P05 const
c callp cmdExc('CLRPFM LIB1/PF1':200)
C Eval *INLR = *ON
在上面的示例中,CmdExc 用于动态调用 QSYS/QCMDEXC。
当我们使用与 EXTPGM 参数相同的程序名称时,它充当从其他程序或过程调用时程序的入口点。
但是在任何情况下,当我们提到任何名称作为示例参数时,EXTPGM 都不会在编译中给出任何错误,但它会在 运行 期间给出错误,因为它试图在 [=] 期间解析名称24=]次。
我收到了 IBM 的回复,基本上 Biswa 正在做某事,只是(在我看来)答案不清楚。
本质上,长 Main 过程名称需要 EXTPGM 以支持递归程序调用。
这是我从 IBM 收到的解释该场景原因的回复:
The incorrect EXTPGM would only matter if there was a call to the main
procedure (the program) within the module.
When the compiler processes the procedure interface, it doesn't know
whether there might be a call that appears later in the module.
我的程序,PKGDAYMONR 有控制选项:
ctl-opt Main( CheckDailyPackages )
CheckDailyPackages 程序有以下 PI:
dcl-pi *n ExtPgm( 'PGMNAME' );
如您所见,ExtPgm
参数不是程序的名称。其实就是模板源里过来的,忘记改了。尽管 ExtPgm
中的名称错误,但程序运行没有问题。
如果我删除该参数并将关键字保留为 ExtPgm
,我会收到以下消息:
RNF3573: A parameter is required for the EXTPGM keyword when the procedure name is longer than 10.
如果我完全从过程界面中删除 ExtPgm
,它也会抱怨:
RNF3834: EXTPGM must be specified on the prototype for the MAIN() procedure.
如果我输入的值无关紧要,为什么我必须指定一个参数?
O/S级别:IBM i 7.2
可能值得 作为服务提供商的缺陷追究;大概对于大多数人来说,这将是 IBM 而不是第三方,因为他们无论如何都必须联系 IBM,因为他们认为问题显然出在他们的编译器上。除此之外,作为我的"Answer",我提出一些想法:
IMO,显然与 OP 一致,在给定场景中命名 ExtPgm 似乎毫无意义。我认为编译器在 混淆 时试图在 隐式生成的原型 的验证中强制执行某些要求,因为只有一个过程接口已提供;即强制执行适用于显式原型的要求,但在给定场景中可能被忽略的要求[因此不再是要求]。我建议虽然 RNF3573 似乎适合诊断显式原型的 EXTPGM 规范,但 IMO 同样的效果是不合适的 [即不应为编译器生成的隐式原型执行验证。
FWiW:是否测试了该自由格式代码的固定格式等效项,以查看是否产生了相同或不同的错误?以下源代码当前包含以 'PGMNAME' 作为参数的 EXTPGM 规范 [即提供 10 字节命名 的任何虚假值来请求编译器,就像在 OP 的场景中所做的那样,只是为了成功编译],但可以用对源进行更改的其他变体,模仿对自由形式变体所做的操作,以测试 same\consistent 验证和错误是否有效:
- 只是编码了 EXTPGM 关键字(w/out 参数);是RNF3573的效果吗?
- EXTPGM 关键字可以省略;是RNF3834的效果吗?
- 完全删除了 D-spec(如果没有定义参数);这不是 OP 中提到的正在尝试的变体之一,所以……效果?
H MAIN(CheckDailyPackages)
*--------------------------------------------------
* Program name: CheckDailyPackages (PGMNAME)
*--------------------------------------------------
P CheckDailyPackages...
P B
D PI EXTPGM('PGMNAME')
/free
// Work is done here
/end-free
P CheckDailyPackages...
P E
EXTPGM 关键字用于定义要原型化的程序的外部名称。如果你提到 EXTPGM 那么程序将被动态调用。
让我们举个例子来解释您的查询。
飞碟
D cmdExc PR ExtPgm('QSYS/QCMDEXC')
D 200A const
D 15P05 const
c callp cmdExc('CLRPFM LIB1/PF1':200)
C Eval *INLR = *ON
在上面的示例中,CmdExc 用于动态调用 QSYS/QCMDEXC。
当我们使用与 EXTPGM 参数相同的程序名称时,它充当从其他程序或过程调用时程序的入口点。
但是在任何情况下,当我们提到任何名称作为示例参数时,EXTPGM 都不会在编译中给出任何错误,但它会在 运行 期间给出错误,因为它试图在 [=] 期间解析名称24=]次。
我收到了 IBM 的回复,基本上 Biswa 正在做某事,只是(在我看来)答案不清楚。
本质上,长 Main 过程名称需要 EXTPGM 以支持递归程序调用。
这是我从 IBM 收到的解释该场景原因的回复:
The incorrect EXTPGM would only matter if there was a call to the main
procedure (the program) within the module.
When the compiler processes the procedure interface, it doesn't know
whether there might be a call that appears later in the module.