In fortran you can define a default value for a variable on declaration which can be overwritten later in the code, also giving default values for all entries in an derived type array as follows:
PROGRAM test
TYPE data
INTEGER :: j=0
CHARACTER(len=10)::label="hello"
END TYPE data
TYPE(data) :: obj(2)
! overwrite the default of 0 in the first array entry
obj(1)%j=6 ! etc etc
END PROGRAM test
all very straightforward. But what is the syntax used for defining a default set of values for all array entries of derived datatypes? I looked up a few tutorials, but none of them addressed this. In other words, to have j=0
in the first element of obj%j
by default and set it to 1 in the second and so on...
PROGRAM test
TYPE data
INTEGER :: j
CHARACTER(len=10)::label
END TYPE data
TYPE(data) :: obj(2)=??? ! what do I put to define an array of default types?
! for example these might be my desired default values
obj(1)%j=0
obj(1)%label="bad"
obj(2)%j=1
obj(2)%label="good"
END PROGRAM test
First a note on terminology: in a statement like
integer, save :: i=1
this doesn't provide a "default" value for i
, it provides an initial value for i. We call this explicit initialization. (Note how I've put the SAVE attribute there just to make it obvious; the attribute is implicit.)
The syntax for such explicit initialization is the same whether the object is of intrinsic or derived type, a scalar or an array:
type(decl_type), save[, attributes] :: myobj = initial_expression
where decl_type
is integer
, real
, my_type
, etc. (type(integer)
can of course be written as the simple integer
.)
For derived type, we just need to find a suitable initialization expression.
For an array myobj
this expression can be a scalar (in which case all elements of the array initially have that value), or an array. Obvious cases use the default structure constructor:
type(my_type), save :: myobj1 = decl_type(comps)
type(my_type), save, dimension(2) :: myobj2 = decl_type(comps)
type(my_type), save, dimension(2) :: myobj3 = [decl_type(comps1), decl_type(comps2)]
If you want to construct an array using the structure constructor, note that you need an array constructor: the structure constructor isn't elemental.
More generally we can use things other than the default structure constructor, but the expression must be a constant expression.
To provide an example suiting the question:
implicit none
type data
integer :: j
character(10) :: label
end type data
type(data), save, dimension(2) :: mydata=[data(0,"bad"), data(1,"good")]
end
Finally, if the derived type has default initialization for components, they can be omitted from the structure constructor:
implicit none
type data
integer :: j=-1
character(10) :: label="nothing"
end type data
type(data), save, dimension(2) :: mydata=data()
end