In the thread Type definition for collecting data, how to ensure that allocatable components of a derived type are dimensioned consistently was discussed, which gave me an idea
It is convenient that you can allocate an array and then pass it to a subroutine
subroutine foo(x)
real, intent(in out) :: x(:)
end subroutine foo
where its size is fixed, although it contents can be changed. If you want to be able to change the size of x in foo it can be declared
real, allocatable, intent(in out) :: x(:)
It would be nice if there were finer control over what you could do to the components of a derived type within a procedure. If it has allocatable components you can pass it as an intent(in)
argument, but then neither values nor the shapes of the components can be changed. If you pass it as intent(in out)
, both the allocatable components’ shapes and values can be changed. If you pass it as intent(out)
, all allocatable components are deallocated. I suggest that for a derived type
type :: t
real, allocatable :: x(:), y(:)
end type t
that you be able to pass it as an argument
subroutine foo(dt)
type(t), intent(in out), fixed_size :: dt
end subroutine foo
where the fixed_size
attribute indicates that components cannot be allocated or deallocated. Within foo, those components could be passed to procedures as assumed shape arrays or as
allocatable, fixed_size
arrays. A declaration
type(t), intent(out), fixed_size :: t
would mean that the components of dt have undefined values but that allocatable components are not deallocated upon entry. The fixed-size
attribute would have a use for allocatable array arguments. For
real, allocatable, intent(in out), fixed_size :: x(:)
The array x
preserves its bounds from the caller, even if the lower bound is not 1. If the declaration were just
real, intent(in out) :: x(:)
the lower bound of x is 1. If the declaration is
real, allocatable, intent(in out) :: x(:)
then x can be allocated or deallocated within the procedure, which is a freedom that may not be wanted.