最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

fortran - Why is the "interface write(formatted)" block being ignored here? - Stack Overflow

programmeradmin1浏览0评论

Based on information found here and in the book Modern Fortran Explained (Incorporating Fortran 2018) by Metcalf, Reid, and Cohen (see section 11.6), I would expect to be able to customise the output of a derived type using an interface write(formatted) block. However, while no compilation errors occur, the interface seems to be ignored.

A self-contained MWE would be:

module foo
    type range
        integer :: lower, upper
    end type

    interface write(formatted)
        module procedure formatted_io_range
    end interface

    private

    public formatted_io_range, range
contains
    subroutine formatted_io_range(value, unit, iotype, vlist, iostat, iomsg)
        class(range), intent(in) :: value
        integer, intent(in) :: unit
        character(len=*), intent(in) :: iotype
        integer, dimension(:), intent(in) :: vlist
        integer, intent(out) :: iostat
        character(len=*), intent(inout) :: iomsg

        write (unit, "('range ',a,': ',i0,',',i0,*(i0))", iostat=iostat, iomsg=iomsg) iotype, value%lower, value%upper, vlist
    end subroutine
end

program main
    use foo

    type(range) :: r

    r = range(1, 2)

    print *, r
    write (*, *) r
    print "(dt)", r
    write (*, "(dt)") r
end

I would expect the output of this program to be

 range LISTDIRECTED: 1,2
 range LISTDIRECTED: 1,2
range DT: 1,2
range DT: 1,2

but compiling with

gfortran -Wall -Wextra -Wpedantic --std=f2018 -Og -fcheck=all foo.f90

and running what I get instead is:

           1           2
           1           2
At line 39 of file foo.f90 (unit = 6, file = 'stdout')
Fortran runtime error: Missing DTIO procedure or intrinsic type passed for item 1 in formatted transfer
(dt)
  ^

Error termination. Backtrace:
#0  0x101111bcf
#1  0x101112777
#2  0x101113047
#3  0x1011f932b
#4  0x10120822f
#5  0x10120833b
#6  0x100f63907
#7  0x100f63c7b

I can get the expected output by replacing the type definition with

type range
    integer :: lower, upper
contains
    procedure :: formatted_io_range
    generic :: write(formatted) => formatted_io_range
end type

but then the interface write(formatted) block isn't needed at all.

Is it possible to use the interface, or is the information in these resources incorrect (or have I misunderstood them)?


Follow up question: both resources say that you can use type(range) instead of class(range) in the formatting routine, but if I try that I get a compilation error:

foo.f90:14:39:

   14 |     subroutine formatted_io_range(value, unit, iotype, vlist, iostat, iomsg)
      |                                       1
Error: DTIO dummy argument at (1) must be of type CLASS

Again, am I doing something wrong or have I misunderstood something?

发布评论

评论列表(0)

  1. 暂无评论