(j3.2006) Output of allocatable components

Van Snyder Van.Snyder
Tue Jul 12 19:24:58 EDT 2011


Consider the subroutine

  subroutine UDIO ( N )
    integer, intent(in) :: N

    type :: T
    end type T

    type :: U
      integer, allocatable :: I(:)
      type(t) :: A
    end type U

    type :: V(N)
      integer, len :: N
      integer :: I(n)
      type(t) :: A
    end type V

    type(u) :: X

    type(v(n)) :: Y

    interface write(unformatted)
      procedure :: UDIO_write
    end interface

    if ( n /= 1 ) stop
    y%i = [ 42 ]
    write ( 10 ) y        ! legal, even though y%i is probably allocatable
    x%i = [ 42 ]
    write ( 10 ) x%i, x%a ! legal because x%i is allocated
    write ( 10 ) x        ! illegal, even though treated as x%i, x%a

  contains

    subroutine UDIO_write ( dtv, unit, iostat, iomsg )
      type(t), intent(in) :: dtv
      integer, intent(in) :: unit
      integer, intent(out) :: iostat
      character(len=*), intent(inout) :: iomsg
      iostat = 0
    end subroutine UDIO_write

  end subroutine UDIO

The objects X and Y almost certainly have the same internal
representation: A descriptor for an allocatable rank-1 integer array.

The statement "write ( 10 ) y" is legal.
The statement "write ( 10 ) x%i, x%a" is legal because x%i is allocated.
The statement "write ( 10 ) x" is illegal, even though x%i is allocated,
and the second bullet in the list in 9.6.3p7 says "x" is "treated as if
all of the components of the object were specified in the list in
component order," that is, as if it were "write ( 10 ) x%i, x%a".  It is
illegal because that sentence continues "those components ... shall not
be pointers or allocatable."

There is a problem for pointers because the graph of storage units to be
written might not be a tree, and indeed might be cyclic.

There is no problem for allocatable components because the graph of
storage units is necessarily a tree.

Even though the representation of objects of types with allocatable
components and with components that are arrays whose extents depend upon
length parameters are probably the same, there is an additional
potential complication for allocatable components because the processor
doesn't know a priori the depth of the tree if the type is recursive --
but it's still a tree.

Is this sufficient technical (not whimsical) justification to prohibit
I/O of objects having allocated allocatable components in cases where
the objects are treated as a list of components, in component order?

If there isn't a technical problem, why couldn't we write "those
components ... shall not be pointers, and allocatable components shall
be allocated"?

If that's not a problem, why couldn't we specify that objects of types
with allocatable components are "treated as if all of the components of
the object were specified in the list in component order"?  Would it
really be necessary to require the components to be accessible?
Wouldn't it be enough to specify that none are pointers, and the
allocatable ones are allocated?

Would it be more palatable if recursive types were prohibited?  In that
case, the processor would know the depth of the tree a priori.





More information about the J3 mailing list