[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP Fortran for OpenVMS
Language Reference Manual


Previous Contents Index

B.6 VIRTUAL Statement

The VIRTUAL statement is included for compatibility with PDP-11 Fortran. It has the same form and effect as the DIMENSION statement (see Section 5.6).

B.7 Alternative Syntax for Octal and Hexadecimal Constants

In HP Fortran, you can use an alternative syntax for octal and hexadecimal constants. The following table shows this alternative syntax and equivalents:

Constant Alternative Syntax Equivalent
Octal ' 0..7 ' O O ' 0..7 '
Hexadecimal ' 0..F ' X Z ' 0..F '

You can use a quotation mark (") in place of an apostrophe in all the above syntax forms.

For More Information:

B.8 Alternative Syntax for a Record Specifier

In HP Fortran, you can specify the following form for a record specifier in an I/O control list:


  • 'r

r

Is a numeric expression with a value that represents the position of the record to be accessed using direct access I/O.

The value must be greater than or equal to 1, and less than or equal to the maximum number of records allowed in the file. If necessary, a record number is converted to integer data type before being used.

If this nonkeyword form is used in an I/O control list, it must immediately follow the nonkeyword form of the io-unit specifier.

B.9 Alternative Syntax for the DELETE Statement

In HP Fortran, you can specify the following form of the DELETE statement when deleting records from a relative file:


  • DELETE (io-unit'r [,ERR=label] [,IOSTAT=i-var])

io-unit

Is the number of the logical unit containing the record to be deleted.

r

Is the positional number of the record to be deleted.

label

Is the label of an executable statement that receives control if an error condition occurs.

i-var

Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

This form deletes the direct access record specified by r.

For More Information:

On the DELETE statement, see Section 12.3.

B.10 Alternative Form for Namelist External Records

In HP Fortran, you can use the following form for an external record:


  • $group-name object = value [object = value]...$[END]

group-name

Is the name of the group containing the objects to be given values. The name must have been previously defined in a NAMELIST statement in the scoping unit.

object

Is the name (or subobject designator) of an entity defined in the NAMELIST declaration of the group name. The object name must not contain embedded blanks, but it can be preceded or followed by blanks.

value

Is a null value, a constant (or list of constants), a repetition of constants in the form r*c, or a repetition of null values in the form r*.

If more than one object=value or more than one value is specified, they must be separated by value separators.

A value separator is any number of blanks, or a comma or slash, preceded or followed by any number of blanks.

For More Information:

On namelist input, see Section 10.3.1.3; output, see Section 10.5.1.3.

B.11 HP Fortran POINTER Statement

The POINTER statement discussed here is different from the one discussed in Section 5.15. It establishes pairs of variables and pointers, in which each pointer contains the address of its paired variable.

This POINTER statement takes the following form:


  • POINTER (pointer,pointee) [,(pointer,pointee)]...

pointer

Is a variable whose value is used as the address of the pointee.

pointee

Is a variable; it can be an array name or array specification.

Rules and Behavior

The following are pointer rules and behavior:

  • Two pointers can have the same value, so pointer aliasing is allowed.
  • When used directly, a pointer is treated like an integer variable. A pointer occupies two numeric storage units, so it is a 64-bit quantity (INTEGER(8)).
  • A pointer cannot be a pointee.
  • A pointer cannot appear in an ASSIGN statement and cannot have the following attributes:
    ALLOCATABLE INTRINSIC POINTER
    EXTERNAL PARAMETER TARGET

    A pointer can appear in a DATA statement with integer literals only.
  • Integers can be converted to pointers, so you can point to absolute memory locations.
  • A pointer variable cannot be declared to have any other data type.
  • A pointer cannot be a function return value.
  • You can give values to pointers by doing the following:
    • Retrieve addresses by using the LOC intrinsic function (or the %LOC built-in function)
    • Allocate storage for an object by using the MALLOC intrinsic function (or by using LIB$GET_VM)

    For example:


    Using %LOC:                  Using MALLOC:          Using LIB$GET_VM:
    
    INTEGER I(10)                INTEGER I(10)          INTEGER I(10)
    INTEGER I1(10) /10*10/       POINTER (P,I)          INTEGER LIB$GET_VM,STATUS
    POINTER (P,I)                P = MALLOC(40)         POINTER (P,I)
    P = %LOC(I1)                 I(2) = I(2) + 1        STATUS = LIB$GET_VM(P,40)
    I(2) = I(2) + 1                                     IF (.NOT. STATUS) CALL EXIT(STATUS)
                                                        I(2) = I(2) + 1
    
  • The value in a pointer is used as the pointee's base address.

The following are pointee rules and behavior:

  • A pointee is not allocated any storage. References to a pointee look to the current contents of its associated pointer to find the pointee's base address.
  • A pointee cannot be data-initialized or have a record structure that contains data-initialized fields.
  • A pointee can appear in only one POINTER statement.
  • A pointee array can have fixed, adjustable, or assumed dimensions.
  • A pointee cannot appear in a COMMON, DATA, EQUIVALENCE, or NAMELIST statement, and it cannot have the following attributes:
    ALLOCATABLE OPTIONAL SAVE
    AUTOMATIC PARAMETER STATIC
    INTENT POINTER TARGET
  • A pointee cannot be:
    • A dummy argument
    • A function return value
    • A record field or an array element
    • Zero-sized
    • An automatic object
    • The name of a generic interface block
  • If a pointee is of derived type, it must be of sequence type.

B.12 Record Structures

HP Fortran record structures are similar to Fortran 95/90 derived types.

A record structure is an aggregate entity containing one or more elements. (Record elements are also called fields or components.) You can use records when you need to declare and operate on multi-field data structures in your programs.

Creating a record is a two-step process:

  1. You must define the form of the record with a multistatement structure declaration.
  2. You must use a RECORD statement to declare the record as an entity with a name. (More than one RECORD statement can refer to a given structure.)

For More Information:

On derived types, see Section 3.3.

B.12.1 Structure Declarations

A structure declaration defines the field names, types of data within fields, and order and alignment of fields within a record. Fields and structures can be initialized, but records cannot be initialized.

A structure declaration takes the following form:


  • STRUCTURE [/structure-name/][field-namelist]
  • field-declaration
  • [field-declaration]
  • ...
  • [field-declaration]
  • END STRUCTURE

structure-name

Is the name used to identify a structure, enclosed by slashes.

Subsequent RECORD statements use the structure name to refer to the structure. A structure name must be unique among structure names, but structures can share names with variables (scalar or array), record fields, PARAMETER constants, and common blocks.

Structure declarations can be nested (contain one or more other structure declarations). A structure name is required for the structured declaration at the outermost level of nesting, and is optional for the other declarations nested in it. However, if you wish to reference a nested structure in a RECORD statement in your program, it must have a name.

Structure, field, and record names are all local to the defining program unit. When records are passed as arguments, the fields in the defining structures within the calling and called subprograms must match in type, order, and dimension.

field-namelist

Is a list of fields having the structure of the associated structure declaration. A field namelist is allowed only in nested structure declarations.

field-declaration

Also called the declaration body. A field-declaration consists of any combination of the following:
  • Type declarations ( Section B.12.1.1)
    These are ordinary Fortran data type declarations.
  • Substructure declarations ( Section B.12.1.2)
    A field within a structure can be a substructure composed of atomic fields, other substructures, or a combination of both.
  • Union declarations ( Section B.12.1.3)
    A union declaration is composed of one or more mapped field declarations.
  • PARAMETER statements
    PARAMETER statements can appear in a structure declaration, but cannot be given a data type within the declaration block.
    Type declarations for PARAMETER names must precede the PARAMETER statement and be outside of a STRUCTURE declaration, as follows:


      INTEGER*4 P
    STRUCTURE /ABC/
      PARAMETER (P=4)
      REAL*4 F
    END STRUCTURE
      REAL*4 A(P)
    

Rules and Behavior

Unlike type declaration statements, structure declarations do not create variables. Structured variables (records) are created when you use a RECORD statement containing the name of a previously declared structure. The RECORD statement can be considered as a kind of type declaration statement. The difference is that aggregate items, not single items, are being defined.

Within a structure declaration, the ordering of both the statements and the field names within the statements is important, because this ordering determines the order of the fields in records.

In a structure declaration, each field offset is the sum of the lengths of the previous fields, so the length of the structure is the sum of the lengths of its fields. The structure is packed; you must explicitly provide any alignment that is needed by including, for example, unnamed fields of the appropriate length.

By default, fields are aligned on natural boundaries; misaligned fields are padded as necessary. To avoid padding of records, you should lay out structures so that all fields are naturally aligned.

To pack fields on arbitrary byte boundaries, you must specify a compiler option. You can also specify alignment for fields by using the cDEC$ OPTIONS or cDEC$ PACK general directive.

A field name must not be the same as any intrinsic or user-defined operator (for example, EQ cannot be used as a field name).

Examples

In the following example, the declaration defines a structure named APPOINTMENT. APPOINTMENT contains the structure DATE (field APP_DATE) as a substructure. It also contains a substructure named TIME (field APP_TIME, an array), a CHARACTER*20 array named APP_MEMO, and a LOGICAL*1 field named APP_FLAG.


STRUCTURE /DATE/
  INTEGER*1 DAY, MONTH
  INTEGER*2 YEAR
END STRUCTURE

STRUCTURE /APPOINTMENT/
  RECORD /DATE/     APP_DATE
  STRUCTURE /TIME/  APP_TIME (2)
    INTEGER*1       HOUR, MINUTE
  END STRUCTURE
  CHARACTER*20      APP_MEMO (4)
  LOGICAL*1         APP_FLAG
END STRUCTURE

The length of any instance of structure APPOINTMENT is 89 bytes.

Figure B-1 shows the memory mapping of any record or record array element with the structure APPOINTMENT.

Figure B-1 Memory Map of Structure APPOINTMENT


For More Information:

  • On compiler options, see the HP Fortran for OpenVMS User Manual.
  • On the cDEC$ OPTIONS directive, see Section 14.14.

B.12.1.1 Type Declarations

The syntax of a type declaration within a record structure is identical to that of a normal Fortran type statement.

The following rules and behavior apply to type declarations in record structures:

  • %FILL can be specified in place of a field name to leave space in a record for purposes such as alignment. This creates an unnamed field.
    %FILL can have an array specification; for example:


    INTEGER %FILL (2,2)
    

    Unnamed fields cannot be initialized. For example, the following statement is invalid and generates an error message:


    INTEGER %FILL /1980/
    
  • Initial values can be supplied in field declaration statements. Unnamed fields cannot be initialized; they are always undefined.
  • Field names must always be given explicit data types. The IMPLICIT statement does not affect field declarations.
  • Any required array dimensions must be specified in the field declaration statements. DIMENSION statements cannot be used to define field names.
  • Adjustable or assumed sized arrays and assumed-length CHARACTER declarations are not allowed in field declarations.

B.12.1.2 Substructure Declarations

A field within a structure can itself be a structured item composed of other fields, other structures, or both. You can declare a substructure in two ways:

  • By nesting structure declarations within other structure or union declarations (with the limitation that you cannot refer to a structure inside itself at any level of nesting).
    One or more field names must be defined in the STRUCTURE statement for the substructure, because all fields in a structure must be named. In this case, the substructure is being used as a field within a structure or union.
    Field names within the same declaration nesting level must be unique, but an inner structure declaration can include field names used in an outer structure declaration without conflict.
  • By using a RECORD statement that specifies another previously defined record structure, thereby including it in the structure being declared.

See the example in Section B.12.1 for a sample structure declaration containing both a nested structure declaration (TIME) and an included structure (DATE).

B.12.1.3 Union Declarations

A union declaration is a multistatement declaration defining a data area that can be shared intermittently during program execution by one or more fields or groups of fields. A union declaration must be within a structure declaration.

Each unique field or group of fields is defined by a separate map declaration.

A union declaration takes the following form:


  • UNION
  • map-declaration
  • map-declaration
  • [map-declaration]
  • ...
  • [map-declaration]
  • END UNION

map-declaration

Takes the following form:

  • MAP
  • field-declaration
  • [field-declaration]
  • ...
  • [field-declaration]
  • END MAP

field-declaration

Is a structure declaration or RECORD statement contained within a union declaration, a union declaration contained within a union declaration, or the declaration of a data field (having a data type) within a union. See Section B.12.1 for a more detailed description of what can be specified in field declarations.

Rules and Behavior

As with normal Fortran type declarations, data can be initialized in field declaration statements in union declarations. However, if fields within multiple map declarations in a single union are initialized, the data declarations are initialized in the order in which the statements appear. As a result, only the final initialization takes effect and all of the preceding initializations are overwritten.

The size of the shared area established for a union declaration is the size of the largest map defined for that union. The size of a map is the sum of the sizes of the fields declared within it.

Manipulating data by using union declarations is similar to using
EQUIVALENCE statements. The difference is that data entities specified within EQUIVALENCE statements are concurrently associated with a common storage location and the data residing there; with union declarations you can use one discrete storage location to alternately contain a variety of fields (arrays or variables).

With union declarations, only one map declaration within a union declaration can be associated at any point in time with the storage location that they share. Whenever a field within another map declaration in the same union declaration is referenced in your program, the fields in the prior map declaration become undefined and are succeeded by the fields in the map declaration containing the newly referenced field.

Examples

In the following example, the structure WORDS_LONG is defined. This structure contains a union declaration defining two map fields. The first map field consists of three INTEGER*2 variables (WORD_0, WORD_1, and WORD_2), and the second, an INTEGER*4 variable, LONG:


STRUCTURE /WORDS_LONG/
  UNION
    MAP
      INTEGER*2  WORD_0, WORD_1, WORD_2
    END MAP
    MAP
      INTEGER*4  LONG
    END MAP
  END UNION
END STRUCTURE

The length of any record with the structure WORDS_LONG is 6 bytes. Figure B-2 shows the memory mapping of any record with the structure WORDS_LONG:

Figure B-2 Memory Map of Structure WORDS_LONG


B.12.2 RECORD Statement

A RECORD statement takes the following form:


  • RECORD /structure-name/record-namelist
  • [, /structure-name/record-namelist]
  • ...
  • [, /structure-name/record-namelist]

structure-name

Is the name of a previously declared structure.

record-namelist

Is a list of one or more variable names, array names, or array specifications, separated by commas. All of the records named in this list have the same structure and are allocated separately in memory.

Rules and Behavior

You can use record names in COMMON and DIMENSION statements, but not in DATA or NAMELIST statements.

Records initially have undefined values unless you have defined their values in structure declarations.


Previous Next Contents Index