[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP Pascal for OpenVMS
User Manual


Previous Contents Index

5.3.3.1 CLASS_S Attribute

When the CLASS_S attribute is used on a formal parameter, the compiler generates a fixed-length scalar descriptor of a variable and passes its address to the called routine. Only ordinal, real, set, pointer, and one-dimensional packed arrays (fixed or conformant) that are of type OF CHAR can have the CLASS_S attribute on the formal parameter.

With the CLASS_S attribute, the type of passing semantics used for the by descriptor argument depends on the use of the VAR keyword. If the formal parameter name is preceded by the reserved word VAR, variable semantics is used; otherwise, value semantics is used.

5.3.3.2 CLASS_A and CLASS_NCA Attributes

When you use the CLASS_A or CLASS_NCA attribute on a formal parameter, the compiler generates an array descriptor and passes its address to the called routine. The type of the CLASS_A and CLASS_NCA parameter must be an array (packed or unpacked, fixed or conformant) of an ordinal or real type.

With the CLASS_A and CLASS_NCA attributes, the type of passing semantics used for the by descriptor argument depends on the use of the VAR keyword. If the formal parameter name is preceded by the reserved word VAR, variable semantics is used; otherwise, value semantics is used.

5.3.3.3 %STDESCR Mechanism Specifier

When you use the %STDESCR mechanism specifier, the compiler generates a fixed-length descriptor of a character-string variable and passes its address to the called routine. Only items of the following types can have the %STDESCR specifier on the actual parameter: character-string constants, string expressions, packed character arrays with lower bounds of 1, and packed conformant arrays with indexes of an integer or integer subrange type. The passing semantics depend on the variable represented by the actual parameter as follows:

  • If the actual parameter is a variable of type PACKED ARRAY OF CHAR, %STDESCR implies variable semantics within the called routine.
  • If the actual parameter is either a variable enclosed in parentheses, an expression, or a VARYING OF CHAR variable, %STDESCR implies foreign semantics.

If the actual parameter is not modified by the called external routine, the corresponding formal parameter should be declared READONLY, saving the copy from having to be made.

The following function declaration requires one fixed-length string descriptor as a parameter:


[ASYNCHRONOUS,EXTERNAL(SYS$SETDDIR)] FUNCTION $SETDDIR
   (%STDESCR New_Dir : PACKED ARRAY [$L1..$U1: INTEGER] OF CHAR;
   VAR Old_Dir_Len : $UWORD := %IMMED 0;
   VAR Old_Dir : [CLASS_S]PACKED ARRAY [$L2..$U2 : INTEGER] OF CHAR
                 := %IMMED 0) : INTEGER; EXTERN;

.
.
.
Status :=  $SETDDIR('[HP_Pascal]');

The actual parameter '[HP_Pascal]' is passed by string descriptor with foreign semantics to the formal parameter New_Dir.

5.3.3.4 %DESCR Mechanism Specifier

When you use the %DESCR mechanism specifier, the parameter generates a descriptor for an ordinal, real, or array variable and passes its address to the called routine. The type of %DESCR parameter can be any ordinal or real type, a VARYING OF CHAR string, or an array (packed or unpacked, fixed or conformant) of an ordinal or real type.

The passing semantics depend on the actual parameter's data type as follows:

  • If the actual parameter is a variable, the %DESCR formal parameter implies variable semantics within the called routine.
  • If the actual parameter is an expression or a variable enclosed in parentheses, %DESCR implies foreign semantics.

If the actual parameter is not modified by the called external routine, the corresponding formal parameter should be declared READONLY, saving the copy from having to be made.

The following function declaration requires a varying-length string descriptor as its parameter:


TYPE
   Vary = VARYING [30] OF CHAR;

VAR
   Obj_String  : Vary;
   Times_Found : INTEGER;

[EXTERNAL] FUNCTION Search_String( %DESCR String_Val : Vary )
   : BOOLEAN; EXTERNAL;

.
.
.
IF Search_String( Obj_String )
   THEN
   Times_Found := Times_Found + 1;

The actual parameter Obj_String is passed by varying string descriptor with variable semantics to the formal parameter String_Val.

For More Information:

  • On descriptor classes and types (HP OpenVMS Calling Standard)

5.3.4 Summary of Passing Mechanisms and Passing Semantics

Table 5-4 summarizes the passing semantics used when various mechanisms are specified on either the formal or the actual parameter. For example, if a variable is passed to a formal parameter that was declared without the keyword VAR and either %REF or [REFERENCE] was specified, then variable passing semantics will be used. Likewise, if a variable is passed to a formal parameter which was declared with the keyword VAR and either %REF or [REFERENCE] was specified, then an error will occur.

If an actual parameter is preceded by an %IMMED specifier, regardless of what passing mechanism is used to declare the formal parameter, foreign semantics would be used, because a specifier appearing on the actual parameter always overrides the semantics specified on the formal parameter.

Table 5-4 Summary of Passing Mechanisms and Passing Semantics
  Actual Parameter
  Variable (Variable) or Expression
Passing Mechanism No VAR
on Formal
VAR
on Formal
No VAR
on Formal
VAR
on Formal
By immediate value
%IMMED or
[IMMEDIATE]

Foreign

Error

Foreign

Error
By reference
Default for non-
conformant or
nonschema
%REF or
[REFERENCE]

Value


Variable

Variable


Error

Value


Foreign

Value 1


Error
By descriptor
Default for
conformant
and schema
[CLASS_S]
[CLASS_A]
[CLASS_NCA]
%STDESCR
%DESCR

Value


Value
Value
Value
Variable
Variable

Variable


Variable
Variable
Variable
Error
Error

Value


Value
Value
Value
Foreign
Foreign

Value 1


Value 1
Value 1
Value 1
Error
Error

1If the formal parameter is declared with the READONLY attribute, then value-passing semantics is used; otherwise, it is an error.

5.4 Passing Parameters between HP Pascal and Other Languages

Passing parameters between HP Pascal and other languages on OpenVMS systems requires some additional knowledge about the semantics and mechanisms used by the HP Pascal and the other compilers involved.

5.4.1 Parameter Mechanisms Versus Parameter Semantics

The Pascal language provides three parameter semantics: "VAR parameters," "value parameters," and "routine parameters." These models define what happens to the parameters, not how the compiler actually implements them. "VAR parameters" are parameters that represent the actual variable passed to the routine. Changes made to the VAR parameter are reflected back to the actual variable passed in to the routine. "Value parameters" are parameters that are local copies of the expression passed into the routine. Changes made to the value parameter are not reflected back to any actual parameter passed in to the routine. "Routine parameters" are parameters that represent entire routines that may be called from inside the called routine.

The HP Pascal compiler provides three parameter mechanisms: "by immediate value," "by reference," and "by descriptor." These forms represent the actual implementation used by the compiler for the parameter. These forms are denoted by the [IMMEDIATE], [CLASS_S], [CLASS_A], and [CLASS_NCA] attributes (note, the [REFERENCE] attribute doesn't just specify a parameter mechanism, but also specifies a parameter semantic model).

HP Pascal also provides a fourth parameter model called "foreign parameters." These parameters become either VAR or value parameters depending on the actual parameter. If the actual parameter is a variable, then the parameter is treated as a VAR parameter. If the actual parameter is an expression, then the parameter is treated as a value parameter. These parameters are denoted by the %REF, %DESCR, and %STDESCR foreign mechanism specifiers and the [REFERENCE] attribute (identical in behavior to the %REF foreign parameter specifier).

Be careful not to confuse the term "value parameter" with the "by immediate value" mechanism. The "value" in "value parameter" describes the semantics of the parameter where changes made to the parameter inside the called routine are not reflected back to the actual parameter. It is a common misconception that HP Pascal uses the "by immediate value" mechanism for "value parameters."

5.4.2 Passing Nonroutine Parameters between HP Pascal and Other Languages

By default, HP Pascal will use the "by reference" mechanism for the following VAR and value parameter types: Ordinal (integer, unsigned, char, Boolean, pointers, subranges, and enumerated types), Real (real, double, quadruple), Record, Array, Set, Varying, and File.

If you want to pass a parameter with the "by immediate value" mechanism, you can place the [IMMEDIATE] attribute on the definition of the formal parameter's definition or use the %IMMED foreign mechanism specifier on the actual parameter to override the default mechanism of the formal parameter. Only ordinal and real types may be passed with the "by immediate value" mechanism. Only value parameters may use the "by immediate value" mechanism.

If you want to accept a value parameter with the "by immediate value," you can place the [IMMEDIATE] attribute on the definition of the formal parameter. Only ordinal and real types may be accepted with the "by immediate value" mechanism.

For example, to pass an integer with the "by immediate value" mechanisn to another routine,


[external] procedure rtn( p : [immediate] integer ); external;

begin
rtn(3);
rtn(some-integer-expression);
end;

If you want to pass a parameter with the "by descriptor" mechanism, you can place the [CLASS_A], [CLASS_S], or [CLASS_NCA] attributes on the formal parameter's definition. You can also use the %DESCR and %STDESCR foreign mechanism specifiers, but be aware that these also imply parameter semantics as well as the parameter-passing mechanism.

When passing values to a subrange parameter in a Pascal routine, the argument must be large enough to hold a value of the subrange's base-type even if the formal parameter contained a size attribute.

When passing Boolean or enumerated-type values to a VAR parameter in a Pascal routine, the calling routine must ensure that the sizes of the Boolean or enumerated-type matches the setting of the /ENUMERATION_SIZE qualifier or [ENUMERATION_SIZE] attribute used in the Pascal routine. For value parameters, you can pass the address of a longword as that will work for either setting.

When passing arrays or records to a Pascal routine, the calling routine must ensure that the array and record has the same layout (including any alignment holes) as chosen by the HP Pascal compiler. You may want to use the /SHOW=STRUCTURE_LAYOUT listing section to help you determine the layout chosen by the HP Pascal compiler.

By default, HP Pascal will use the "by descriptor" mechanism for VAR and value conformant parameters. For conformant-varying parameters, HP Pascal uses a CLASS_VS desciptor. For conformant-array parameters, HP Pascal uses a CLASS_NCA descriptor on OpenVMS I64 and OpenVMS Alpha systems and a CLASS_A descriptor on OpenVMS VAX systems.

Using a conformant-varying parameter or STRING schema parameter with a routine not written in Pascal is not very common since the called routine does not know how to deal with these strings. If you just are passing a string expression to the non-Pascal routine, using a conformant PACKED ARRAY OF CHAR is the right solution.

Since HP Pascal will use either a CLASS_A or CLASS_NCA descriptor for the conformant PACKED ARRAY OF CHAR, but other languages will expect either a CLASS_S descriptor or the string "by reference", you will need to use either the [CLASS_S] attribute or the %REF foreign mechanism specifier.

For example, to pass a string expression to Fortran (which expects a CLASS_S descriptor),


[external] procedure fortrtn(
                p : [class_s] packed array [l..u:integer] of char); external;

  begin
  fortrtn('string');
  fortrtn(some-string-expression);
  end;

To pass a string expression to C (which expects a "by-reference" parameter and a null-terminated string),


[external] procedure crtn(
                %ref p : packed array [l..u:integer] of char); external;

  begin
  crtn('string'(0));
  crtn(some-string-expression+'0');
  end;

HP Pascal on OpenVMS I64 and OpenVMS Alpha systems has additional support to deal with null-terminated strings.

For More Information

  • HP Pascal Language Reference Manual

When passing strings to an HP Pascal routine from another language, you must use a descriptor if the Pascal formal parameter is a conformant parameter. HP Pascal cannot accept a conformant parameter with the "by reference" mechanism. For conformant array parameters, you must generate a CLASS_A descriptor on OpenVMS or a CLASS_NCA descriptor on OpenVMS Alpha unless you select another descriptor class using the [CLASS_S], [CLASS_A], or [CLASS_NCA] attributes. For conformant varying parameters, you must generate a CLASS_VS descriptor on both platforms.

If you wish to use the "by reference" mechanism to pass strings into a Pascal routine, you must define a Pascal datatype that represents a fixed-length string (or varying-string with a maximum size) and use that datatype in the formal parameter definition.

The HP Pascal schema type STRING is passed by CLASS_VS descriptor. Other HP Pascal schema types use private data structures when passed between routines and cannot be accessed from routines written in other languages.

5.4.3 Passing Routine Parameters between HP Pascal and Other Languages

On OpenVMS I64 Systems:

By default, HP Pascal on OpenVMS I64 systems passes the address of a function descriptor for PROCEDURE or FUNCTION parameters. The presence of the [UNBOUND] attribute or the %IMMED foreign mechanism specifier has no effect over the generated code since the function descriptors in the OpenVMS Calling Standard allow any combination of bound and unbound routines to be passed around and invoked.

On OpenVMS I64 systems, HP Pascal expects the address of a function descriptor for routine parameters. In all OpenVMS I64 languages, asking for the address of a routine yields the address of its function descriptor, since the actual address of the instructions is not useful by itself.

On OpenVMS Alpha Systems:

By default, HP Pascal on OpenVMS Alpha systems passes the address of a procedure descriptor for PROCEDURE or FUNCTION parameters. The presence of the [UNBOUND] attribute or the %IMMED foreign mechanism specifier has no effect over the generated code since the procedure descriptors in the OpenVMS Calling Standard allow any combination of bound and unbound routines to be passed around and invoked.

On OpenVMS Alpha systems, HP Pascal expects the address of a procedure descriptor for routine parameters. In all OpenVMS Alpha languages, asking for the address of a routine yields the address of its procedure descriptor, since the actual address of the instructions is not useful by itself.

On OpenVMS VAX Systems:

By default, HP Pascal on OpenVMS VAX will pass the address of a BPV (Bound Procedure Value) for PROCEDURE or FUNCTION parameters. The BPV is a 2 longword structure with the 1st longword being the address of the entry mask of the routine being passed; the 2nd longword is either a 0 or a frame-pointer for any uplevel references that the called routine may attempt to perform. If you use the [UNBOUND] attribute on the PROCEDURE or FUNCTION parameter, the compiler still passes the address of a BPV, but the 2nd longword will always be zero. If you use the %IMMED foreign mechanism specifier along with the [UNBOUND] attribute, HP Pascal will pass the address of the routine with the "by immediate" mechanism.

For example, if you want to pass a Pascal routine to an external routine that just expects the address of the routine (like a C routine or system service),


[external] procedure crtn(
                %immed [unbound] procedure p); external;

  procedure x;
    begin ... end;

  begin
  crtn(x);
  end;

Most system routines expect to be called in this fashion. A few routines like EDT$EDIT actually expect BPVs and not just entry point addresses.

On OpenVMS VAX, HP Pascal only accepts a routine parameter by BPV. To pass a routine from a non-Pascal routine to a Pascal routine, you must use the [UNBOUND] attribute on the formal routine parameter and you must pass the address of a longword containing the address of the routine's entry point.


Previous Next Contents Index