I've run into a possible bug with derived type IO when I have a derived type with a private component array of derived types. I've included a example code snippet below that should reproduce the problem (I'm using ifort version 14.0.2.114). To summarize the problem, when I try to write my derived type using a formatted write statement it output the public component of the derived type, as expected, and then it outputs the first n-1 values of the component derived type, which is both private and not called in the main formatted write statement.
In the sample code below the write statement should output:
1.0000
but instead outputs
1.0000 2.0000 2.0000 2.0000 2.0000
Sample code:
module DTIO implicit none ! derived types: type T1 private real :: x contains procedure, private :: T1_write_formatted generic :: write(formatted) => T1_write_formatted end type T1 type T2 private real :: x type(T1) :: y(5) contains procedure, private :: T2_write_formatted generic :: write(formatted) => T2_write_formatted end type T2 ! interfaces: interface T1 module procedure :: T1_constructor end interface T1 interface T2 module procedure :: T2_constructor end interface T2 contains pure function T1_constructor( x ) result( val ) real, intent(in) :: x type(T1) :: val val%x = x end function T1_constructor pure function T2_constructor( x ) result( val ) real, intent(in) :: x type(T2) :: val val%x = x val%y = T1(2.0*x) end function T2_constructor subroutine T1_write_formatted( self, unit, iotype, v_list, iostat, iomsg ) class(T1), intent(in) :: self integer , intent(in) :: unit character(*), intent(in) :: iotype integer , intent(in) :: v_list(:) integer , intent(out) :: iostat character(*), intent(inout) :: iomsg ! local variables: character(:), allocatable :: fmt ! determine format if (len_trim(iotype) > 0) then if (iotype(1:2) == 'DT') then if (len_trim(iotype) > 2) then fmt = '('//iotype(3:)//')' write(unit, fmt=fmt, iostat=iostat, iomsg=iomsg) self%x deallocate(fmt) else write(unit, *, iostat=iostat, iomsg=iomsg) self%x end if else if (iotype == 'LISTDIRECTED') then write(unit, *, iostat=iostat, iomsg=iomsg) self%x else if (iotype == 'NAMELIST') then write(unit, *, iostat=iostat, iomsg=iomsg) self%x end if end if end subroutine T1_write_formatted subroutine T2_write_formatted( self, unit, iotype, v_list, iostat, iomsg ) class(T2), intent(in) :: self integer , intent(in) :: unit character(*), intent(in) :: iotype integer , intent(in) :: v_list(:) integer , intent(out) :: iostat character(*), intent(inout) :: iomsg ! local variables: character(:), allocatable :: fmt ! determine format if (len_trim(iotype) > 0) then if (iotype(1:2) == 'DT') then if (len_trim(iotype) > 2) then fmt = '('//iotype(3:)//')' write(unit, fmt=fmt, iostat=iostat, iomsg=iomsg) self%x deallocate(fmt) else write(unit, *, iostat=iostat, iomsg=iomsg) self%x end if else if (iotype == 'LISTDIRECTED') then write(unit, *, iostat=iostat, iomsg=iomsg) self%x else if (iotype == 'NAMELIST') then write(unit, *, iostat=iostat, iomsg=iomsg) self%x end if end if end subroutine T2_write_formatted end module DTIO program main use DTIO implicit none ! local parameters: type(T2) :: var var = T2(1.0) write(*,'(A)') 'formatting: unspecified' write(*,*) var write(*,'(A)') '' write(*,'(A)') 'formatting: specified' write(*,'(DT"F10.4")') var end program main