Prototypes

A prototype is a definition of the call interface. It includes the following information:
  • Whether the call is bound (procedure) or dynamic (program)
  • How to find the program or procedure (the external name)
  • The number and nature of the parameters
  • Which parameters must be passed, and which are optionally passed
  • Whether operational descriptors should be passed
  • The data type of the return value, if any (for a procedure)

There is a special kind of prototype called an "overloaded prototype". It allows you to call one of several different candidate prototypes using the name of the overloaded prototype for the call operations. See OVERLOAD(prototype1 { : prototype2 ...}) for more information.

A prototype may be explicitly or implicitly defined. If the procedure is called from a different RPG module, the prototype must be explicitly specified in both the calling module and the module that defines the procedure. If the procedure is only called within the same module, the prototype may be explicitly defined, or it may be omitted. If the prototype is omitted, the compiler will implicitly define it from the procedure interface.

For modules that call a procedure that is defined in a different module, a prototype must be included in the definition specifications of the program or procedure that makes the call. The prototype is used by the compiler to call the program or procedure correctly, and to ensure that the caller passes the correct parameters.

By default, the compiler does not require a prototype for the main procedure or for exported procedures. You can use the REQPREXP command parameter or Control specification keyword to cause the compiler to issue a warning or error message at compile time if a prototype is not specified for the main procedure or for an exported procedure. See REQPREXP(*NO | *WARN | *REQUIRE).

The following rules apply to prototype definitions.
  • A prototype must have a name. If the keyword EXTPGM or EXTPROC is specified on the prototype definition, then any calls to the program or procedure use the external name specified for that keyword. If neither keyword is specified, then the external name is the prototype name in uppercase.
  • In free form, specify the DCL-PR operation code followed by the prototype name and keywords; in fixed form, specify PR in the Definition-Type entry (positions 24-25). Any parameter definitions must immediately follow the PR specification. In free-form, the prototype definition ends with the END-PR statement; in fixed form, the prototype definition ends with the first definition specification with non-blanks in positions 24-25 or by a non-definition specification.
  • Specify any of the following keywords as they pertain to the call interface:
    EXTPROC(name)
    The call will be a bound procedure call that uses the external name specified by the keyword.
    EXTPGM(name)
    The call will be an external program call that uses the external name specified by the keyword.
    OPDESC
    Operational descriptors are to be passed with the parameters that are described in the prototype.
    RTNPARM
    The return value is to be handled as a parameter. This may improve performance when calling the procedure, especially for large return values.
  • A return value (if any) is specified on the PR definition. Specify the length and data type of the return value. In addition, you may specify the following keywords for the return value:
    DATFMT(fmt)
    The return value has the date format specified by the keyword.
    DIM(N)
    The return value is an array or data structure with N elements.
    LIKEDS(data_structure_name)
    The returned value is a data structure. (You cannot refer to the subfields of the return value when you call the procedure.)
    LIKEREC(name{,type})
    The returned value is a data structure defined like the specified record format name.
    Note: You cannot refer to the subfields of the return value when you call the procedure.
    LIKE(name)
    The return value is defined like the item specified by the keyword.
    PROCPTR
    The return value is a procedure pointer.
    TIMFMT(fmt)
    The return value has the time format specified by the keyword.
    VARYING{(2|4)}
    A character, graphic, or UCS-2 return value has a variable-length format.

For information on these keywords, see Definition-Specification Keywords. Figure 1 shows a prototype for a subprocedure CVTCHR that takes a numeric input parameter and returns a character string. Note that there is no name associated with the return value. For this reason, you cannot display its contents when debugging the program.

Figure 1. Prototype for CVTCHR
      * The returned value is the character representation of
      * the input parameter NUM, left-justified and padded on
      * the right with blanks.
     D CVTCHR          PR            31A
     D   NUM                         31P 0   VALUE
      * The following expression shows a call to CVTCHR.  If
      * variable rrn has the value 431, then after this EVAL,
      * variable msg would have the value
      *    'Record 431 was not found.'
     C                   EVAL      msg = 'Record '
     C                                 + %TRIMR(CVTCHR(RRN))
     C                                 + ' was not found '

If you are writing a prototype for an exported subprocedure or for a main procedure, put the prototype in a /COPY file and copy the prototype into the source file for both the callers and the module that defines the procedure. This coding technique provides maximum parameter-checking benefits for both the callers and the procedure itself, since they all use the same prototype.