Intel® Fortran Compiler 18.0 Developer Guide and Reference
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:
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 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. 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:
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. 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:
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. |
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.
The PRIVATE keyword can only be specified if the derived-type definition is in the specification part of a module.
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.
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.
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.
! 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