# TYPE Statement (Derived Types)

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

TYPE [[,attr-list] :: ] name [(type-param-name-list)]

[type-param-def-stmts]

[PRIVATE statement or SEQUENCE statement]. . .

[component-definition]. . .

[type-bound-procedure-part]

END TYPE [name]

attr-list | Is one of the following: access-spec Is the PUBLIC or PRIVATE attribute. The attribute can only be specified if the derived-type definition is in the specification part of a module. BIND(C) EXTENDS (parent-type-name) where parent-type-name is the name of a previously defined extensible type. ABSTRACT The same attr must not appear more than once in any given derived-type statement. If the type definition contains or inherits a deferred binding, ABSTRACT must appear. The EXTENDS and ABSTRACT attributes apply to type extension and extended types. If ABSTRACT is specified, the type is an abstract type and it must be extensible. A derived type that does not have the SEQUENCE or BIND(C) attribute is extensible. Conversely, a derived type that has the SEQUENCE or BIND(C) attribute is not extensible.
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.
type-param-name-list | Is a list of type parameter names separated by commas. For more information, see Parameterized Derived-Type Declarations.
type-param-def-stmts | Is one or more INTEGER declarations of the type parameters named in the type-param-name-list. For more information, see Parameterized Derived-Type Declarations.
component-definition | Is one or more type declaration statements or procedure pointer statements defining the component of derived type. The first component definition can be preceded by an optional PRIVATE or SEQUENCE statement. (Only one PRIVATE and only one 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. Procedure pointer component definitions are described in Procedure Pointers as Derived-Type Components. The syntax for a type declaration component definition is described below.
type-bound-procedure-part | Is a CONTAINS statement, optionally followed by a PRIVATE statement, and one or more procedure binding statements (specific, generic, or final). For more information, see Type-Bound Procedures.

A type declaration component definition takes the following form:

type[ [, attr] :: ] component[( a-spec)] [[ coarray-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 or the ALLOCATABLE attribute follows this specifier, the type can also be the type being defined or any accessible derived type, whether previously defined or not.
attr | Is at most one of the following: An optional POINTER attribute for a pointer component An optional ALLOCATABLE attribute for a scalar component An optional DIMENSION or ALLOCATABLE attribute for an array component You cannot specify both the ALLOCATABLE and POINTER attribute. An optional access specifier, PUBLIC or PRIVATE An optional CODIMENSION [coarray-spec] to specify a coarray An optional CONTIGUOUS attribute if the object is contiguous Each attribute can only appear once in a given component definition. If neither the POINTER nor the ALLOCATABLE attribute is specified, type must specify an intrinsic type or a previously defined derived type. If neither the POINTER nor the ALLOCATABLE attribute is specified, each a-spec must be an explicit-shape specification. If the POINTER or ALLOCATABLE attribute is specified, each component array specification a-spec must be a deferred shape specification (d-spec). If a coarray-spec appears, it must be a deferred specification list consisting of one or more colons (:), the component must have the ALLOCATABLE attribute, and the component must not be of type C_PTR or C_FUNPTR from the intrinsic module ISO_C_BINDING or of type TEAM_TYPE from the intrinsic module ISO_FORTRAN_ENV. A data component whose type has a coarray ultimate component must be a nonpointer nonallocatable scalar and must not be a coarray. If the CONTIGUOUS attribute is specified, the component must be an array with the POINTER attribute.
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 component is an array and the array bounds are not specified here, they must be specified following the DIMENSION attribute.
coarray-spec | Is a deferred-coshape specification. The left bracket and right bracket are required.
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 one of the following: = constant expression for nonpointer components => NULL( ) for pointer components 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 constant 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.

The default accessibility attribute for a module is PUBLIC unless it has been changed by a PRIVATE statement with no entity-list.

A PUBLIC or PRIVATE keyword can only appear on the TYPE statement of a derived-type definition, or on a component or type-bound procedure declaration of the type if the derived-type definition is in the specification part of a module.

The PRIVATE statement can only be specified in the component-definition or type-bound-procedure-part if the derived-type definition is in the specification part of a module. A PRIVATE statement inside a component-definition part specifies that the default accessibility of all components of the derived type are PRIVATE. Similarly, a PRIVATE statement inside a type-bound-procedure-part specifies that the default accessibility of the type bound procedures of the derived type are PRIVATE. If the default accessibility of components or type-bound procedures is PRIVATE, individual components or type-bound procedures can be declared PUBLIC, overriding the default accessibility attribute.

If a type definition is PRIVATE, the type name and the structure constructor for the type are accessible only within the module containing the definition and in the descendants of that module.

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 EXTENDS appears and the type being defined has a coarray ultimate component, its parent type must have a coarray ultimate component.

Data entities in different scoping units also have the same type if the following is true:

- They are declared with reference to different derived-type definitions that specify the same type name.

- All have the SEQUENCE property.

- All have the BIND attribute.

- They have no components with PRIVATE accessibility.

- They have type parameters and components that agree in order, name, and attributes.

Otherwise, they are of different derived types.

A data component is a coarray if the component declaration contains a coarray specification. If the component declaration contains a coarray specification, it specifies the corank.

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

- The derived type cannot be a SEQUENCE type.

- The derived type must not have type parameters.

- The derived type must not have the EXTENDS attribute.

- The derived type must not have a type-bound-procedure-part.

- Each component of the derived type must be a nonpointer, nonallocatable data component with interoperable type and type parameters.

## Example

     !   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
        SEQUENCE
        TYPE (mem_name) :: name
        INTEGER age
        CHARACTER (LEN = 20) specialty
    END TYPE member

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

     USE, INTRINSIC :: ISO_C_BINDING
     TYPE, BIND(C) :: pair
       INTEGER(C_INT) :: i, j
     END TYPE
     TYPE (pair) :: 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

The following program shows how you initialize components of a derived-type object:

    TYPE list_node
       CHARACTER(20)                :: street_name = “ “
       INTEGER(2)                   :: street_number = 0
       INTEGER(2)                   :: apt_number = -1
       CHARACTER(20)                :: city = “ “
       CHARACTER(2)                 :: state = “NH”
       INTEGER(4)                   :: zip = 0
       TYPE (list_node), POINTER    :: next => NULL()
    END TYPE

    TYPE (list_node) :: x = list_node (zip = 03054)
    PRINT *, x%state, x%zip
    END

The above prints the following:

            NH 3054

Coarrays are a Fortran 2008 feature. The following example shows a derived-type definition with a coarray component:

    TYPE NEW_TYPE
       REAL,ALLOCATABLE,CODIMENSION[:,:,:] :: NEW(:,:,:)
    END TYPE NEW_TYPE

An object of type NEW_TYPE must be a scalar and it cannot be a pointer, allocatable, or a coarray.

The following example shows a derived-type definition containing a coarray-spec:

    type t
       integer :: k
       real, allocatable :: x (:,:)[:,:]
    end type t

In the following example, when the assignment to DEST occurs, DEST%TA is unallocated: it is first allocated with the size of SOURCE%TA and then the value of SOURCE%TA is assigned into DEST%TA:

    TYPE T
      INTEGER I
    END TYPE T
    TYPE T2
      TYPE (T), ALLOCATABLE :: TA
    END TYPE T2

    TYPE (T2) SOURCE, DEST

    ALLOCATE(SOURCE%TA)
    DEST = SOURCE

The use of allocatable components of recursive type can involve direct recursion, in which the type has a component that is the same type as its parent. The following example creates a five-element linked list using allocatable components of recursive type:

    TYPE T
    INTEGER I
    TYPE(T), ALLOCATABLE :: NEXT
    END TYPE

    TYPE (T), ALLOCATABLE, TARGET :: ORIG, COPY
    TYPE (T), POINTER :: TA

    ALLOCATE(ORIG)
    TA => ORIG

    DO I=1,5
      TA%I = I
      ALLOCATE(TA%NEXT)
      TA => TA%NEXT
    END DO

By using allocatable components rather than pointer components, there is no need to explicitly nullify component NEXT - it is set to an unallocated state automatically by the compiler. Because the semantics of ALLOCATE(SOURCE=) require the allocation and copying of all allocated allocatable components from ORIG into COPY, we can create a complete, unique copy of the entire linked list in one easy statement:

    ALLOCATE(COPY, SOURCE=ORIG)

In addition to direct recursion, indirect recursion or forward referencing can also be used. In the following example, component A of type T is of type T2, a forward reference to a type not yet defined, while component B of type T2 is of type T:

    TYPE T
    TYPE(T2), ALLOCATABLE :: A
    END TYPE

    TYPE T2
    TYPE(T), ALLOCATABLE :: B
    END TYPE

    TYPE(T2) TY

Parent topic: T to Z

## See Also

Type Declarations
Procedure Pointers
Type-Bound Procedures
Passed-Object Dummy Arguments
Type Extension
Procedure Pointers as Derived-Type Components
DIMENSION
PRIVATE
PUBLIC
RECORD
SEQUENCE
STRUCTURE...END STRUCTURE
Derived Data Types
Default Initialization
Structure Components
Structure Constructors