The C quicksort function qsort takes a compare routine. For instance, to sort an array of integers, the following function (which use the byvalue attribute twice - for the reasons discussed above) could be used:
comp2:
proc( key, element )
returns( fixed bin(31) byvalue );
dcl (key, element) pointer byvalue;
dcl word based fixed bin(31);
select;
when( key->word < element->word )
return( -1 );
when( key->word = element->word )
return( 0 );
otherwise
return( +1 );
end;
end;And the C qsort function could be used with this compare routine to sort an array of integers, as in the following code fragment:
dcl a(1:4) fixed bin(31) init(19,17,13,11); put skip data( a ); call qsort( addr(a), dim(a), stg(a(1)), comp2 ); put skip data( a );
But since C function pointers are not the same as PL/I ENTRY variables, the C qsort function must not be declared as simply:
dcl qsort ext('qsort')
entry( pointer,
fixed bin(31),
fixed bin(31),
entry returns( byvalue fixed bin(31) )
)
options( byvalue nodescriptor );Recall that a PL/I ENTRY variable may point to a nested function (and thus requires a backchain address as well as an entry point address). But a C function pointer is limited in pointing to a non-nested function only and so, a PL/I ENTRY variable and a C function pointer do not even use the amount of storage.
However, a C function pointer is equivalent to the new PL/I type: a LIMITED ENTRY. and hence the C qsort function could be declared as:
dcl qsort ext('qsort')
entry( pointer,
fixed bin(31),
fixed bin(31),
limited entry
returns( byvalue fixed bin(31) )
)
options( byvalue nodescriptor );