gfortran 中的`generic :: write(formatted)` 子例程被其他派生类型调用
`generic :: write(formatted)` subroutines in gfortran being called by other derived types
我正在使用几种派生类型。出于调试目的,我想使用 generic :: write(formatted)
.
将它们很好地打印在屏幕上
这是一个示例程序,说明了我的意思:
program main
use :: test_mod
implicit none
type(test1) :: t1
type(test2) :: t2
t1 = test1(name="t1")
t2 = test2(name="t2", t1)
print *, 'Test1:', t1
print *, 'Test2:', t2
end program
这是模块:
module test_mod
implicit none
private
public :: test1, test2
type :: test1
character(2) :: name
contains
procedure, private :: test1_writef
generic :: write(formatted) => test1_writef
end type test1
type :: test2
character(2) :: name
type(test1) :: t1
contains
procedure, private :: test2_writef
generic :: write(formatted) => test2_writef
end type test2
contains
subroutine test1_writef(self, unit, iotype, v_list, iostat, iomsg)
class(test1), intent(in) :: self ! Object to write.
integer, intent(in) :: unit ! Internal unit to write to.
character(*), intent(in) :: iotype ! LISTDIRECTED or DTxxx
integer, intent(in) :: v_list(:) ! parameters from fmt spec.
integer, intent(out) :: iostat ! non zero on error, etc.
character(*), intent(inout) :: iomsg ! define if iostat non zero.
write (unit, "(a)", IOSTAT=iostat, IOMSG=iomsg) self%name
end subroutine test1_writef
subroutine test2_writef(self, unit, iotype, v_list, iostat, iomsg)
class(test2), intent(in) :: self ! Object to write.
integer, intent(in) :: unit ! Internal unit to write to.
character(*), intent(in) :: iotype ! LISTDIRECTED or DTxxx
integer, intent(in) :: v_list(:) ! parameters from fmt spec.
integer, intent(out) :: iostat ! non zero on error, etc.
character(*), intent(inout) :: iomsg ! define if iostat non zero.
write (unit, "(a, ' <', a, '>')", IOSTAT=iostat, IOMSG=iomsg) self%name, self%t1
end subroutine test2_writef
end module test_mod
运行这个程序我期望获得:
Test1: t1
Test2: t2 <t1>
但是我得到的是 gfortran:
Test1: t1
Test2: t2 <>
"t1" 字符串 未写入屏幕。
我正在使用这个版本的 gfortran:
[egissi@shibax ~]$ gfortran --version
GNU Fortran (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
我知道我可以用 self%t1%name
替换 self%t1
,但我的类型比那复杂得多,我最好不要在其他派生类型中重复相同的格式。
我错过了什么?我怎样才能获得这种行为?
要使用定义的输出过程,它必须以某种方式 "selected"。在list-directed输出
print *, 'Test1:', t1
print *, 'Test2:', t2
程序test1_writef
和test2_writef
可用于有效项目t1
和t2
。因此使用它们。
但是,对于子输出
write (unit, "(a, ' <', a, '>')", IOSTAT=iostat, IOMSG=iomsg) self%name, self%t1
我们现在有了明确的格式 ("(a,' <',a,'>')"
)。这里有效的项目 self%name
和 self%t1
被明确地编辑为字符。要请求根据 test1_writef
处理对象 self%t1
,必须明确使用 dt
编辑描述符:
write (unit, "(a, ' <', dt, '>')", IOSTAT=iostat, IOMSG=iomsg) self%name, self%t1
我正在使用几种派生类型。出于调试目的,我想使用 generic :: write(formatted)
.
这是一个示例程序,说明了我的意思:
program main
use :: test_mod
implicit none
type(test1) :: t1
type(test2) :: t2
t1 = test1(name="t1")
t2 = test2(name="t2", t1)
print *, 'Test1:', t1
print *, 'Test2:', t2
end program
这是模块:
module test_mod
implicit none
private
public :: test1, test2
type :: test1
character(2) :: name
contains
procedure, private :: test1_writef
generic :: write(formatted) => test1_writef
end type test1
type :: test2
character(2) :: name
type(test1) :: t1
contains
procedure, private :: test2_writef
generic :: write(formatted) => test2_writef
end type test2
contains
subroutine test1_writef(self, unit, iotype, v_list, iostat, iomsg)
class(test1), intent(in) :: self ! Object to write.
integer, intent(in) :: unit ! Internal unit to write to.
character(*), intent(in) :: iotype ! LISTDIRECTED or DTxxx
integer, intent(in) :: v_list(:) ! parameters from fmt spec.
integer, intent(out) :: iostat ! non zero on error, etc.
character(*), intent(inout) :: iomsg ! define if iostat non zero.
write (unit, "(a)", IOSTAT=iostat, IOMSG=iomsg) self%name
end subroutine test1_writef
subroutine test2_writef(self, unit, iotype, v_list, iostat, iomsg)
class(test2), intent(in) :: self ! Object to write.
integer, intent(in) :: unit ! Internal unit to write to.
character(*), intent(in) :: iotype ! LISTDIRECTED or DTxxx
integer, intent(in) :: v_list(:) ! parameters from fmt spec.
integer, intent(out) :: iostat ! non zero on error, etc.
character(*), intent(inout) :: iomsg ! define if iostat non zero.
write (unit, "(a, ' <', a, '>')", IOSTAT=iostat, IOMSG=iomsg) self%name, self%t1
end subroutine test2_writef
end module test_mod
运行这个程序我期望获得:
Test1: t1
Test2: t2 <t1>
但是我得到的是 gfortran:
Test1: t1
Test2: t2 <>
"t1" 字符串 未写入屏幕。
我正在使用这个版本的 gfortran:
[egissi@shibax ~]$ gfortran --version
GNU Fortran (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
我知道我可以用 self%t1%name
替换 self%t1
,但我的类型比那复杂得多,我最好不要在其他派生类型中重复相同的格式。
我错过了什么?我怎样才能获得这种行为?
要使用定义的输出过程,它必须以某种方式 "selected"。在list-directed输出
print *, 'Test1:', t1
print *, 'Test2:', t2
程序test1_writef
和test2_writef
可用于有效项目t1
和t2
。因此使用它们。
但是,对于子输出
write (unit, "(a, ' <', a, '>')", IOSTAT=iostat, IOMSG=iomsg) self%name, self%t1
我们现在有了明确的格式 ("(a,' <',a,'>')"
)。这里有效的项目 self%name
和 self%t1
被明确地编辑为字符。要请求根据 test1_writef
处理对象 self%t1
,必须明确使用 dt
编辑描述符:
write (unit, "(a, ' <', dt, '>')", IOSTAT=iostat, IOMSG=iomsg) self%name, self%t1