C 関数の宣言の変換は間違いを起こしやすいかもしれません。 例えば、次に示す C 関数 fread の宣言を考えてみましょう。
size_t fread( void *,
size_t,
size_t,
FILE *);これを次のように変換します。
dcl fread ext
entry( pointer,
type size_t,
type size_t,
type file_Handle )
returns( type size_t );プラットフォームによっては、C の名前に大文字小文字の区別があるため、 これではリンクが正常に行われない場合があります。 この種のリンカーの問題を防ぐために最適な方法は、 external 属性の拡張形式を使用して、大文字小文字混合 の名前を指定することです。 したがって、例えば fread の宣言は次のように改良できます。
dcl fread ext('fread')
entry( pointer,
type size_t,
type size_t,
type file_Handle )
returns( type size_t );ただし、これは正しく実行されません。 この原因は、PL/I パラメーターはデフォルトで byaddr になり、 一方で C パラメーターはデフォルトで byvalue になるからです。 このため、パラメーターに byvalue 属性を追加して この問題を修正します。
dcl fread ext('fread')
entry( pointer byvalue,
type size_t byvalue,
type size_t byvalue,
type file_Handle byvalue )
returns( type size_t );ただし、図 66 で戻り値がどのように設定されているか に注意してください。4 番目のパラメーター (一時 _temp5 のアドレス) が 関数 fread に渡され、この関数はそのアドレスに整数の戻りコードを 置くことになります。 これは、returns に byaddr 属性が適用されている 場合に値を戻す方法の規則で、PL/I はデフォルトでこの規則を使用します。
* read_In = fread( addr(buffer), 1, stg(buffer), file );
*
L r4,FILE(,r13,176)
L r1,fread(,r5,12)
LA r2,_temp5(,r13,420)
LA r8,BUFFER(,r13,184)
L r15,&EPA_&WSA(,r1,8)
L r0,&EPA_&WSA(,r1,12)
ST r0,_CEECAA_(,r12,500)
LA r1,#MX_TEMP1(,r13,152)
ST r8,#MX_TEMP1(,r13,152)
LA r8,1
ST r8,#MX_TEMP1(,r13,156)
ST r7,#MX_TEMP1(,r13,160)
ST r4,#MX_TEMP1(,r13,164)
ST r2,#MX_TEMP1(,r13,168)
BALR r14,r15
L r0,_temp5(,r13,420)
ST r0,READ_IN(,r13,180)
C の戻り値は byvalue なので、これは正しく実行されません。 このため、byvalue 属性をもう 1 つ追加してこの問題を修正します。
dcl fread ext('fread')
entry( pointer byvalue,
type size_t byvalue,
type size_t byvalue,
type file_Handle byvalue )
returns( type size_t byvalue );図 68 で戻り値がどのように設定されているかに注目して ください。追加のアドレスは渡されず、戻り値がレジスター 15 に戻される だけです。
* read_In = fread( addr(buffer), 1, stg(buffer), file );
*
L r2,FILE(,r13,176)
L r1,fread(,r5,12)
LA r7,BUFFER(,r13,184)
L r15,&EPA_&WSA(,r1,8)
L r0,&EPA_&WSA(,r1,12)
ST r0,_CEECAA_(,r12,500)
LA r1,#MX_TEMP1(,r13,152)
ST r7,#MX_TEMP1(,r13,152)
LA r7,1
ST r7,#MX_TEMP1(,r13,156)
ST r4,#MX_TEMP1(,r13,160)
ST r2,#MX_TEMP1(,r13,164)
BALR r14,r15
LR r0,r15
ST r0,READ_IN(,r13,180)