On Tuesday, October 4, 2016 at 2:54:49 PM UTC-4, steve kargl wrote:
> ..
>
> Example code? It is difficult to fix bugs that are not reported via
> channels. ..
@steve kargl,
I would have expected you to have realized that in this case, it's NOT a bug that I am pointing out to gfortran developers, rather it is a note from the Fortran standard. I'm lousy at standard-speak and my own understanding of the underlying comp. sci. principles and programming language semantics and the data and organization foundation of Fortran is worse: at times, I find figuring out the standard is as difficult as interpreting a nation's constitution, with me almost always getting it wrong.
For the situation at hand, I do not know if my own reading is correct, or that the other compiler is right.
So I was hesitant to go into further details beyond pointing out the relevant text from the standard; I would guess gfortran developers working on UDDTIO would be quite familiar with the context of the presented note, for after all the very task they embarked on was to implement a pending standard feature from over 12 years ago. So my hope is not to BIAS the developers in any way, let them do their own investigation if they are so inclined, and follow up as they find appropriate in full conformance with their own interpretation of the standard.
But now, should a gfortran developer insist on some code, here's one, a trivial extension of the earlier one I had provided. And anyone following up on it should keep the above comments in mind:
-- begin --
module string_m
implicit none
private
type, public :: string_t
private
character(len=:), allocatable :: m_s
contains
private
procedure, pass(this), private :: assign_s
procedure, pass(this), private :: write_s
generic, public :: assignment(=) => assign_s
generic, public :: write(formatted) => write_s
end type string_t
!.. Named constants
integer, parameter :: MAXLENS = 256
contains
subroutine assign_s( this, rhs )
class(string_t), intent(inout) :: this
character(len=*), intent(in) :: rhs
this%m_s = rhs
return
end subroutine assign_s
subroutine write_s(this, lun, iotype, vlist, istat, imsg)
! argument definitions
class(string_t), intent(in) :: this
integer, intent(in) :: lun
character(len=*), intent(in) :: iotype
integer, intent(in) :: vlist(:)
integer, intent(out) :: istat
character(len=*), intent(inout) :: imsg
! local variable
character(len=MAXLENS) :: sfmt
integer :: filesize
inquire( unit=lun, size=filesize, iostat=istat, iomsg=imsg )
if (istat /= 0) return
sfmt = "(A)"
if ( (iotype == "DT").and.(size(vlist) >= 1) ) then
! vlist(1) to be used as the field width of the character component.
write(sfmt,"(A,I2,A)", iostat=istat, iomsg=imsg ) "(A", vlist(1), ")"
if (istat /= 0) return
end if
write(lun, fmt=sfmt, iostat=istat, iomsg=imsg) this%m_s
return
end subroutine write_s
end module string_m
program p
use string_m, only : string_t
type(string_t) :: s
character(len=12) :: msg
integer :: istat
character(len=256) :: imsg
s = "Hello World!"
write( msg, "(DT)", iostat=istat, iomsg=imsg ) s
if (istat /= 0) then
print *, "write failed: istat = ", istat
print *, trim(imsg)
stop
end if
print *, "msg = ", msg
stop
end program p
-- end --
Upon execution with gfortran (GCC 7.0 development trunk),
msg = Hello World!
Whereas with Intel Fortran,
write failed: istat = 90
User Defined I/O procedure returned error 90, message: INQUIRE of internal unit-number is always an error (NOTE: unit identifies a file)