VMS Help  —  FORTRAN  Data  Derived Types
  Like intrinsic data types, a Fortran 95/90 derived data type has a
  name, a set of associated values, a way to denote the values, and
  operations to manipulate and interpret these values.

  The names of the intrinsic data types are predefined, while the
  names of derived types are defined in derived-type definitions.

  A derived-type definition specifies the name of the type and the
  types of its components.  A derived type can be resolved into
  "ultimate" components that are either of intrinsic type or are
  pointers.

  The set of values for a specific derived type consists of all
  possible sequences of component values permitted by the definition
  of that derived type.  Structure constructors are used to specify
  values of derived types.

  Nonintrinsic assignment for derived-type entities must be defined
  by a subroutine with an ASSIGNMENT interface.  Any operation on
  derived-type entities must be defined by a function with an
  OPERATOR interface.  Arguments and function values can be of any
  intrinsic or derived type.

1  –  Type Definitions

  A derived-type definition specifies the name of a user-defined type
  and the types of its components.  It takes the following form:

    TYPE [[, PRIVATE or PUBLIC] :: ] name
      [PRIVATE or SEQUENCE]...
      comp-def
      [comp-def]...
    END TYPE [name]

    name      Is the name of the derived type. It must not be
              the same as the name of any intrinsic type, or
              the same as the name of a derived type that can be
              accessed from a module.

    comp-def  There must be at least one.  It takes the following
              form:

       type [ [, attr-list] ::] comp [(a-spec)] [*char-len] [init_ex]

    type      Is a type specifier.  It can be an intrinsic type
              or a previously defined derived type. (If the POINTER
              attribute follows this specifier, the type can also be
              any accessible derived type, including the type
              being defined.)

    attr-list Is an optional list of component attributes POINTER
              or DIMENSION.  You can specify one or both attributes.
              If DIMENSION is specified, it can be followed by an
              array specification.

    comp      Is the name of the component being defined.

    a-spec    Is an optional array specification, enclosed in
              parentheses.  If POINTER is specified, the array is
              deferred-shape; otherwise, it is explicit-shape.

              In an explicit-shape specification, each bound must
              be a constant scalar integer expression.

    char-len  Is an optional scalar integer literal constant; it
              must be preceded by an asterisk (*).  This parameter
              can only be specified if the component is of type
              CHARACTER.

    init_ex   Is an initialization expression or, for pointer
              objects, =>NULL().

  If a name is specified following the END TYPE statement, it must be
  the same name that follows TYPE in the derived type statement.

  Within a scoping unit, a derived-type name can only be defined
  once.  If the same derived-type name appears in a derived-type
  definition in another scoping unit, it is treated independently.

  A component name has the scope of the derived-type definition only.
  Therefore, the same name can be used in another derived-type
  definition in the same scoping unit.

  Two entities can have the same derived type in the following cases:

   o  If they are both declared to be of the same derived type, and
      the derived-type definition can be accessed from the same
      module, the same scoping unit, or a host scoping unit.

   o  If they are both declared to be of the same derived type, and
      the derived-type definition can be accessed from the same
      scoping unit or a host scoping unit.

   o  If they are both declared in a derived-type definition
      specifying SEQUENCE (they both have sequence type).

      A sequence type can be defined in each scoping unit that needs
      to access the type.  Each derived-type definition must specify
      the same name, the keyword SEQUENCE, and have components that
      agree in order, name, and attributes.  (No private components
      are allowed in a sequence type.)

  The same PRIVATE or SEQUENCE statements can only appear once in a
  given derived-type definition.

  If SEQUENCE is present, all derived types specified in component
  definitions must be sequence types.

  The PUBLIC or PRIVATE keywords can only appear if the derived-type
  definition is in the specification part of a module.

  The POINTER or DIMENSION attribute can only appear once in a given
  comp-def.

  A component is an array if the component definition contains a
  DIMENSION attribute or an array specification.  If the component
  definition contains an array specification, the array bounds should
  be specified there; otherwise, they must be specified following the
  DIMENSION attribute.

  If an initialization expression ("init_ex") appears for a
  nonpointer component, the component (in any object of the type) is
  initially defined with the value determined from the initialization
  expression.  The initialization expression is evaluated in the
  scoping unit of the type definition.

  The initialization expression overrides any default initial value
  specified for the component.  Explicit initialization in a type
  declaration statement overrides default initialization.

  If POINTER appears in the comp-def, the component is a pointer.
  Pointers can have an association status of associated,
  disassociated, or undefined.  If no default initialization status
  is specified, the status of the pointer is undefined.  To specify
  disassociated status for a pointer component, use =>NULL().

2  –  Components

  A reference to a component of a derived-type structure takes the
  following form:

    parent [%component [(s-list)]]... %component [(s-list)]

    parent    Is the name of a scalar or array of derived type.
              The percent sign (%) is called a component selector.

    component Is the name of a component of the immediately
              preceding parent or component.

    s-list    Is a list of one or more subscripts. If the list
              contains subscript triplets or vector subscripts,
              the reference is to an array section.

              Each subscript must be a scalar numeric expression
              with a value that is within the bounds of its
              dimension.

              The number of subscripts in any s-list must equal
              the rank of the immediately preceding parent or
              component.

  Each parent or component (except the rightmost) must be of derived
  type.

  The parent or one of the components can have nonzero rank (be an
  array).  Any component to the right of a parent or component of
  nonzero rank must not have the POINTER attribute.

  The rank of the structure component is the rank of the part (parent
  or component) with nonzero rank (if any); otherwise, the rank is
  zero.  The type and type parameters (if any) of a structure
  component are those of the rightmost part name.

  The structure component must not be referenced or defined before
  the declaration of the parent object.

  If the parent object has the INTENT, TARGET, or PARAMETER
  attribute, the structure component also has the attribute.

2.1  –  Examples

  The following example shows a derived-type definition with two
  components:

    TYPE EMPLOYEE
      INTEGER ID
      CHARACTER(LEN=40) NAME
    END TYPE EMPLOYEE

  The following shows how to declare a variable CONTRACT of type
  EMPLOYEE:

    TYPE(EMPLOYEE) :: CONTRACT

  Note that both examples started with the keyword TYPE.  The first
  (initial) statement of a derived-type definition is called a
  derived-type statement, while the statement that declares a
  derived-type object is called a TYPE statement.

  The following example shows how to reference component ID of parent
  structure CONTRACT:

    CONTRACT%ID

  The following example shows a derived type with a component that is
  a previously defined type:

    TYPE DOT
      REAL X, Y
    END TYPE DOT
    ....
    TYPE SCREEN
      TYPE(DOT) C, D
    END TYPE SCREEN

  The following declares a variable of type SCREEN:

    TYPE(SCREEN) M

  Variable M has components M%C and M%D (both of type DOT); M%C has
  components M%C%X and M%C%Y of type REAL.

  The following example shows a derived type with a component that is
  an array:

    TYPE CAR_INFO
      INTEGER YEAR
      CHARACTER(LEN=15), DIMENSION(10) :: MAKER
      CHARACTER(LEN=10) MODEL, BODY_TYPE*8
      REAL PRICE
    END TYPE
    ...
    TYPE(CAR_INFO) MY_CAR

  Note that MODEL has a character length of 10, but BODYTYPE has a
  character length of 8.  You can assign a value to a component of a
  structure; for example:

    MY_CAR%YEAR = 1985

  The following shows an array structure component:

    MY_CAR%MAKER

  In the preceding example, if a subscript list (or substring) was
  appended to MAKER, the reference would not be to an array structure
  component, but to an array element or section.

  Consider the following:

    TYPE CHARGE
      INTEGER PARTS(40)
      REAL LABOR
      REAL MILEAGE
    END TYPE CHARGE

    TYPE(CHARGE) MONTH
    TYPE(CHARGE) YEAR(12)

  Some valid array references for this type follow:

    MONTH%PARTS(I)           ! An array element
    MONTH%PARTS(I:K)         ! An array section
    YEAR(I)%PARTS            ! An array structure component
                             !  (a whole array)

    YEAR(J)%PARTS(I)         ! An array element
    YEAR(J)%PARTS(I:K)       ! An array section
    YEAR(J:K)%PARTS(I)       ! An array section
    YEAR%PARTS(I)            ! An array section

  The following example shows a derived type with a pointer component
  that is of the type being defined:

    TYPE NUMBER
      INTEGER NUM
      TYPE(NUMBER), POINTER :: BEFORE_NUM
      TYPE(NUMBER), POINTER :: AFTER_NUM
    END TYPE

  A type such as this can be used to construct linked lists of
  objects of type NUMBER.

  The following example shows a private type:

    TYPE, PRIVATE :: SYMBOL
      LOGICAL TEST
      CHARACTER(LEN=50) EXPLANATION
    END TYPE SYMBOL

  This type is private to the module.  The module can be used by
  another scoping unit, but type SYMBOL is not available.

  The following example shows a derived-type definition that is
  public with components that are private:

    MODULE MATTER
      TYPE ELEMENTS
        PRIVATE
        INTEGER C, D
      END TYPE
    ...
    END MODULE MATTER

  In this case, components C and D are private to type ELEMENTS, but
  type ELEMENTS is not private to MODULE MATTER.  Any program unit
  that uses the module MATTER can declare variables of type ELEMENTS,
  and pass as arguments values of type ELEMENTS.

  This design allows you to change components of a type without
  affecting other program units that use the module.

  If a derived type is needed in more than one program unit, the
  definition should be placed in a module and accessed by a USE
  statement whenever it is needed, as follows:

    MODULE STUDENTS
      TYPE STUDENT_RECORD
      ...
      END TYPE
    CONTAINS
      SUBROUTINE COURSE_GRADE(...)
      TYPE(STUDENT_RECORD) NAME
      ...
      END SUBROUTINE
    END MODULE STUDENTS
    ...

    PROGRAM SENIOR_CLASS
      USE STUDENTS
      TYPE(STUDENT_RECORD) ID
      ...
    END PROGRAM

  Program SENIOR_CLASS has access to type STUDENT_RECORD, because it
  uses module STUDENTS.  Module procedure COURSE_GRADE also has
  access to type STUDENT_RECORD, because the derived-type definition
  appears in its host.

3  –  Constructors

  A structure constructor lets you specify scalar values of a derived
  type.  It takes the following form:

    d-name (expr-list)

    d-name    Is the name of the derived type.

    expr-list Is a list of expressions specifying component
              values.  The values must agree in number and
              order with the components of the derived type.

              If necessary, values are converted (according
              to the rules of assignment), to agree with their
              corresponding components in type and kind type
              parameters.

  A structure constructor must not appear before its derived type is
  defined.

  If a component of the derived type is an array, the shape in the
  expression list must conform to the shape of the component array.

  If a component of the derived type is a pointer, the value in the
  expression list must evaluate to an object that would be a valid
  target in a pointer assignment statement.  (A constant is not a
  valid target in a pointer assignment statement.)

  If all the values in a structure constructor are constant
  expressions, the constructor is a derived-type constant expression.

3.1  –  Examples

  Consider the following derived-type definition:

    TYPE EMPLOYEE
      INTEGER ID
      CHARACTER(LEN=40) NAME
    END TYPE EMPLOYEE

  This can be used to produce the following structure constructor:

    EMPLOYEE(3472, "John Doe")

  The following example shows a type with a component of derived
  type:

    TYPE ITEM
      REAL COST
      CHARACTER(LEN=30) SUPPLIER
      CHARACTER(LEN=20) ITEM_NAME
    END TYPE ITEM

    TYPE PRODUCE
      REAL MARKUP
      TYPE(ITEM) FRUIT
    END TYPE PRODUCE

  In this case, you must use an embedded structure constructor to
  specify the values of that component; for example:

    PRODUCE(.70, ITEM (.25, "Daniels", "apple"))
Close Help