TYPE Statement (Derived Types)

Statement: Declares a variable to be a derived type. It specifies the name of the user-defined type and the types of its components.

Syntax

TYPE [[, type-attr-spec-list] :: ] name
     component-definition
     [component-definition]. . .
END TYPE [ name ]

type-attr-spec-list
Is access-spec or BIND (C).

access-spec
Is the PUBLIC or PRIVATE keyword. The keyword can only be specified if the derived-type definition is in the specification part of a module.

name
Is the name of the derived data 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.

component-definition
Is one or more type declaration statements defining the component of derived type.

The first component definition can be preceded by an optional PRIVATE or SEQUENCE statement. (Only one PRIVATE or SEQUENCE statement can appear in a given derived-type definition.)

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

A component definition takes the following form:

type [ [, attr ] :: ] component [(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
Is an optional POINTER attribute for a pointer component, or an optional DIMENSION or ALLOCATABLE attribute for an array component. You cannot specify both the ALLOCATABLE and POINTER attribute. If DIMENSION is specified, it can be followed by an array specification.

Each attribute can only appear once in a given component-definition.

component
Is the name of the component being defined.

a-spec
Is an optional array specification, enclosed in parentheses. If POINTER or ALLOCATABLE 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.

If the array bounds are not specified here, they must be specified following the DIMENSION attribute.

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 components, => NULL( ). This is a Fortran 95 feature.

If init-ex is specified, a double colon must appear in the component definition. The equals assignment symbol (=) can only be specified for nonpointer components.

The initialization expression is evaluated in the scoping unit of the type definition.

Description

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

A derived type can be defined only once in a scoping unit. 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 data entities have the same type if they are both declared to be of the same derived type (the derived-type definition can be accessed from a module or a host scoping unit).

If the entities are in different scoping units, they can also have the same derived type if they are declared with reference to different derived-type definitions, and if both derived-type definitions have all of the following:

If BIND (C) is specified, the following rules apply:

See Also

DIMENSION, MAP...END MAP, PRIVATE, PUBLIC, RECORD, SEQUENCE, STRUCTURE...END STRUCTURE, Derived Data Types, Default Initialization, Structure Components Structure Constructors, Building Applications: Handling User-Defined Types

Examples

 !   DERIVED.F90
 !   Define a derived-type structure,
 !   type variables, and assign values

     TYPE member
       INTEGER age
       CHARACTER (LEN = 20) name
     END TYPE member

     TYPE (member) :: george
     TYPE (member) :: ernie

     george     = member( 33, 'George Brown' )
     ernie%age  = 56
     ernie%name = 'Ernie Brown'

     WRITE (*,*) george
     WRITE (*,*) ernie
     END

The following shows another example of a derived type:

TYPE mem_name
  SEQUENCE
  CHARACTER (LEN = 20) lastn
  CHARACTER (LEN = 20) firstn
  CHARACTER (len = 3) cos   ! this works because COS is a component name
END TYPE mem_name
TYPE member
    TYPE (mem_name) :: name
    SEQUENCE
    INTEGER age
    CHARACTER (LEN = 20) specialty
END TYPE member

In the following example, a and b are both variable arrays of derived type pair:

 TYPE (pair)
   INTEGER i, j
 END TYPE
 TYPE (pair), DIMENSION (2, 2) :: a, b(3)

The following example shows how you can use derived-type objects as components of other derived-type objects:

 TYPE employee_name
   CHARACTER(25) last_name
   CHARACTER(15) first_name
 END TYPE
 TYPE employee_addr
   CHARACTER(20) street_name
   INTEGER(2) street_number
   INTEGER(2) apt_number
   CHARACTER(20) city
   CHARACTER(2) state
   INTEGER(4) zip
 END TYPE

Objects of these derived types can then be used within a third derived-type specification, such as:

 TYPE employee_data
   TYPE (employee_name) :: name
   TYPE (employee_addr) :: addr
   INTEGER(4) telephone
   INTEGER(2) date_of_birth
   INTEGER(2) date_of_hire
   INTEGER(2) social_security(3)
   LOGICAL(2) married
   INTEGER(2) dependents
 END TYPE