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------------------------------------------>< |
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.
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:
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.
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.
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 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--)--' |
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:
>>-type_name--(--expr_list--)---------------------------------->< |
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.
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