IBM Books

Language Reference


Derived Types

You can create additional data types, known as derived types, from intrinsic data types and other derived types. You require a type definition to define the name of the derived type (type_name), as well as the data types and names of the components of the derived type.



>>-DERIVED_TYPE_statement--------------------------------------><
 

>>-+------------------------+----------------------------------><
   '-PRIVATE_SEQUENCE_block-'
 

>>-component_def_stmt_block------------------------------------><
 

>>-END_TYPE_statement------------------------------------------><
 

DERIVED_TYPE_statement
See Derived Type for syntax details.

PRIVATE_SEQUENCE_block
includes the PRIVATE statement (keyword only) and/or the SEQUENCE statement. Only one of each statement can be specified. See PRIVATE and SEQUENCE for details on syntax.

component_def_stmt_block

consists of one or more type declaration statements to define the components of the derived type. The type declaration statements can specify only the DIMENSION and POINTER attributes. See Type Declaration for detailed syntax and information.

In addition, Fortran 95 allows you to specify a default initialization for each component in the definition of a derived type. See Type Declaration for detailed syntax and information.

END_TYPE_statement
See END TYPE.

Direct components of a derived type are:

Each derived type is resolved into ultimate components of intrinsic data type.

The type name is a local entity. It cannot be the same name as any of the intrinsic data types except BYTE and DOUBLE COMPLEX.

The END TYPE statement can optionally contain the same type_name as specified on the TYPE statement.

The components of a derived type can specify any of the intrinsic data types. Components can also be of a previously defined derived type. A pointer component can be of the same derived type that it is a component of. Within a derived type, the names of components must be unique, although they can be different from names outside the scope of the derived-type definition. Components that are declared to be of type CHARACTER must have length specifications that are constant specification expressions; asterisks are not allowed as length specifiers. Nonpointer array components must be declared with constant dimension declarators. Pointer array components must be declared with a deferred_shape_spec_list.

By default, no storage sequence is implied by the order of the component definitions. However, if you specify the SEQUENCE statement, the derived type becomes a sequence derived type. For a sequence derived type, the order of the components specifies a storage sequence for objects declared with this derived type. If a component of a sequence derived type is of a derived type, that derived type must also be a sequence derived type.

The size of a sequence derived type is equal to the number of bytes of storage needed to hold all of the components of that derived type.

Use of sequence derived types can lead to misaligned data, which can adversely affect the performance of the program.

The PRIVATE statement can only be specified if the derived-type definition is within the specification part of a module. If a component of a derived type is of a type declared to be private, either the derived-type definition must contain the PRIVATE statement or the derived type itself must be private.

If a type definition is private, the following are accessible only within the defining module:

If a derived-type definition contains a PRIVATE statement, its components are accessible only within the defining module, even if the derived type itself is public. Structure components can only be used in the defining module.

A component of a derived-type entity cannot appear as an input/output list item if any ultimate component of the object cannot be accessed by the scoping unit of the input/output statement. A derived-type object cannot appear in a data transfer statement if it has a component that is a pointer.

A scalar entity of derived type is called a structure. A scalar entity of sequence derived type is called a sequence structure. The type specifier of a structure must include the TYPE keyword, followed by the name of the derived type in parentheses. See TYPE for details on declaring entities of a specified derived type. The components of a structure are called structure components. A structure component is one of the components of a structure or is an array whose elements are components of the elements of an array of derived type.

An object of a private derived type cannot be used outside the defining module.

A candidate data object for default initialization is a named data object that:

  1. is of derived type with default initialization specified for any of its direct components.

  2. has neither the POINTER, nor the ALLOCATABLE attribute.

  3. is not use or host associated.

  4. is not a pointee.

A default initialization for a non-pointer component will take precedence over any default initialization appearing for any direct component of its type.

If a dummy argument with INTENT(OUT) is of a derived type with default initialization, it must not be an assumed-size array. If a non-pointer object or subobject has been specified with default initialization in a type definition, it must not be initialized by a DATA statement. You must not specify data objects of derived type with default initializations in a common block.

You can specify a default initialization for some components of a derived type, but it is not necessary for every component.

You can specify default initialization for a storage unit that is storage associated. However, the objects or subobjects supplying the default initialization must be of the same type. The objects or subobjects must also have the same type parameters and supply the same value for the storage unit.

Unlike explicit initialization, it is not necessary for a data object to have the SAVE attribute for component default initialization to have an impact. In addition, default initialization does not imply the SAVE attribute.

A direct component will receive an initial value if you specify a default initialization on the corresponding component definition in the type definition, regardless of the accessibility of the component.

For candidate data objects for default initialization, their nonpointer direct components are either initially defined, or become defined by their corresponding default initialization expressions, and their pointer direct components are either initially disassociated, or become disassociated if one of the following conditions is met:

Allocation of an object of a derived type in which you specify a default initialization for a direct component will cause the component to:

In a subprogram with an ENTRY statement, default initialization only occurs for the dummy arguments that appear in the argument list of the procedure name referenced. If such a dummy argument has the OPTIONAL attribute, default initialization will only occur if the dummy argument is present.

Module data objects, which are of derived type with default initializations must have the SAVE attribute, if they are candidate data objects for default initialization.

Determining Type for Derived Types

Two data objects have the same derived type if they are declared with reference to the same derived-type definition.

If the data objects are in different scoping units, they can still have the same derived type. Either the derived-type definition is accessible via host or use association, or the data objects reference their own derived-type definitions with the following conditions:

A derived-type definition that specifies SEQUENCE is not the same as a definition declared to be private or that has components that are private.

Example of Determining Type with Derived Types

PROGRAM MYPROG
 
TYPE NAME                         ! Sequence derived type
   SEQUENCE
   CHARACTER(20) LASTNAME
   CHARACTER(10) FIRSTNAME
   CHARACTER(1)  INITIAL
END TYPE NAME
TYPE (NAME) PER1
 
CALL MYSUB(PER1)
PER1 = NAME('Smith','John','K')   ! Structure constructor
CALL MYPRINT(PER1)
 
CONTAINS
  SUBROUTINE MYSUB(STUDENT)       ! Internal subroutine MYSUB
     TYPE (NAME) STUDENT          ! NAME is accessible via host association
              ·
  END SUBROUTINE MYSUB
END
 
SUBROUTINE MYPRINT(NAMES)         ! External subroutine MYPRINT
  TYPE NAME                       ! Same type as data type in MYPROG
     SEQUENCE
     CHARACTER(20) LASTNAME
     CHARACTER(10) FIRSTNAME
     CHARACTER(1)  INITIAL
  END TYPE NAME
  TYPE (NAME) NAMES               ! NAMES and PER1 from MYPROG
  PRINT *, NAMES                  ! have the same data type
END SUBROUTINE

Structure Components

Structure components can be of any explicit type, including derived type.
Note:The case in which a structure component has a subobject that is an array or array section requires some background information from Array Sections, and is explained in Array Sections and Structure Components. The following rules for scalar structure components apply also to structure components that have array subobjects.

You can refer to a specific structure component using a component designator. A scalar component designator has the following syntax:



>>-name----+----------------------+----------------------------->
           '-(--int_expr_list--)--'
 
>-----+----------------------------------------------+---------->
      |  .----------------------------------------.  |
      |  V                                        |  |
      '----%comp_name---+----------------------+--+--'
                        '-(--int_expr_list--)--'
 
>-----%comp_name-+----------------------+----------------------><
                 '-(--int_expr_list--)--'
 

name
is the name of an object of derived type

comp_name
is the name of a derived-type component

int_expr
is a scalar integer or real expression called a subscript expression

The structure component has the same type, type parameters, and POINTER attribute (if any) as the right-most comp_name. It inherits any INTENT, TARGET, and PARAMETER attributes from the parent object.

Notes:

  1. Each comp_name must be a component of the immediately preceding name or comp_name.

  2. The name and each comp_name, except the right-most, must be of derived type.

  3. The number of subscript expressions in any int_expr_list must equal the rank of the preceding name or comp_name.

  4. If name or any comp_name is the name of an array, it must have an int_expr_list.

  5. The right-most comp_name must be scalar.

Structure Constructor



>>-type_name--(--expr_list--)----------------------------------><
 

type_name
is the name of the derived type

expr
is an expression. Expressions are defined under 5.0 , Expressions and Assignment.

A structure constructor allows a scalar value of derived type to be constructed from an ordered list of values. A structure constructor must not appear before the definition of the referenced derived type.

expr_list contains one value for each component of the derived type. The sequence of expressions in the expr_list must agree in number and order with the components of the derived type. The type and type parameters of each expression must be assignment-compatible with the type and type parameters of the corresponding component. Data type conversion is performed if necessary.

A component that is a pointer can be declared with the same type that it is a component of. If a structure constructor is created for a derived type containing a pointer, the expression corresponding to the pointer component must evaluate to an object that would be an allowable target for such a pointer in a pointer assignment statement.

Examples of Derived Types

Example 1:

MODULE PEOPLE
  TYPE NAME
     SEQUENCE                     ! Sequence derived type
     CHARACTER(20) LASTNAME
     CHARACTER(10) FIRSTNAME
     CHARACTER(1)  INITIAL
  END TYPE NAME
 
  TYPE PERSON                     ! Components accessible via use
                                  ! association
     INTEGER AGE
     INTEGER BIRTHDATE(3)         ! Array component
     TYPE (NAME) FULLNAME         ! Component of derived type
  END TYPE PERSON
END MODULE PEOPLE
PROGRAM TEST1
  USE PEOPLE
  TYPE (PERSON) SMITH, JONES
  SMITH = PERSON(30, (/6,30,63/), NAME('Smith','John','K'))
                                  ! Nested structure constructors
  JONES%AGE = SMITH%AGE           ! Component designator
  CALL TEST2
  CONTAINS
 
  SUBROUTINE TEST2
    TYPE T
      INTEGER EMP_NO
      CHARACTER, POINTER :: EMP_NAME(:)  ! Pointer component
    END TYPE T
    TYPE (T) EMP_REC
    CHARACTER, TARGET :: NAME(10)
    EMP_REC = T(24744,NAME)              ! Pointer assignment occurs
  END SUBROUTINE                         ! for EMP_REC%EMP_NAME
END PROGRAM

Example 2:

PROGRAM LOCAL_VAR
   TYPE DT
      INTEGER A
      INTEGER :: B = 80
   END TYPE
 
   TYPE(DT) DT_VAR                      ! DT_VAR%B IS INITIALIZED
END PROGRAM LOCAL_VAR

Example 3:

MODULE MYMOD
   TYPE DT
      INTEGER :: A = 40
      INTEGER, POINTER :: B => NULL()
   END TYPE
END MODULE
 
PROGRAM DT_INIT
   USE MYMOD
   TYPE(DT), SAVE :: SAVED(8)            ! SAVED%A AND SAVED%B ARE INITIALIZED
   TYPE(DT) LOCAL(5)                     ! LOCAL%A LOCAL%B ARE INITIALIZED
END PROGRAM


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ] © Copyright IBM Corporation 1990, 1998