It would be easy to mistranslate the declarations for the C functions. For instance, you could take the following declaration for the C function fread:
size_t fread( void *,
size_t,
size_t,
FILE *);and translate it to:
dcl fread ext
entry( pointer,
type size_t,
type size_t,
type file_Handle )
returns( type size_t );On some platforms, this would not link successfully because C names are case sensitive. In order to prevent this kind of linker problem, it is best to specify the name in mixed case using the extended form of the external attribute. So, for instance, the declare for fread would be better as:
dcl fread ext('fread')
entry( pointer,
type size_t,
type size_t,
type file_Handle )
returns( type size_t );But this wouldn't run right, because while PL/I parameters are byaddr by default, C parameters are byvalue by default; so we fix that by adding the byvalue attribute to the parameters:
dcl fread ext('fread')
entry( pointer byvalue,
type size_t byvalue,
type size_t byvalue,
type file_Handle byvalue )
returns( type size_t );But note how the return value is set in Figure 66: a fourth parameter (the address of the temporary _temp5) is passed to the function fread, which is then expected to place the return code in the integer at that address. This is the convention for how values are returned when the byaddr attribute applies to returns, and PL/I uses this convention by default.
* 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)
This wouldn't run right, because C return values are byvalue. So, we fix that with one more byvalue attribute.
dcl fread ext('fread')
entry( pointer byvalue,
type size_t byvalue,
type size_t byvalue,
type file_Handle byvalue )
returns( type size_t byvalue );Note how the return value is set now in Figure 68: no extra address is passed, and the return value is simply returned in register 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)