3

我想将 fortran写语句包装在包含一些额外调试逻辑的自定义子例程或函数中。

但我目前坚持定义函数/子例程的原型。这可能吗?如果是,如何?

4

3 回答 3

3

您的问题的标题显示出一种误解,尽管文字表明您知道得更好。尽管如此,为了记录,write它是一个 Fortran 语句,它既不是子程序也不是函数。

我认为你有很多选择。我偶尔使用的一种方法是编写一个返回字符串的函数。也许

function error_message(error)
    character(len=*), intent(in) :: error
    character(len=:), allocatable :: error_message
    error_message = 'ERROR: '//trim(error)
end function error_message

然后你可以像这样使用它

write(*,*) error_message('Oh s**t')

您当然可以编写具有副作用的子例程或函数,包括写入输出通道,但如果您采用这种方法,则必须小心遵守递归 i/o 的规则。

编辑

在OP的评论之后。

如果您想关闭调试消息,您可以选择将它们定向到空设备或文件,例如/dev/null在 Linux 或NULWindows 上。就像是

integer, parameter :: debug_channel = 99
logical, parameter :: debugging = .false.
...
if (debugging) then
   open(debug_channel, file='NUL')
else
   open(debug_channel, file='debuglog'
end if

接着

write(debug_channel,*) 'message'
于 2013-11-11T12:56:53.697 回答
2

完成大部分您想要的相对简单的方法是简单地将if内联放在每个受调试控制的写入前面:

    if(debug)write(..,..).. 

其中 debug 是一个全局逻辑值,甚至是:

    if(debugf(level))write(..,..).. 

其中逻辑函数 debugf 根据某个参数确定是否写入。

于 2013-11-12T22:31:09.670 回答
1

除了其他答案,您也许可以避免使用if (debug) write...派生类型 IO。

我说“可以”,因为除非您已经有合适的结构,否则这很愚蠢,而且编译器支持目前很少见。

但是,作为示例,使用 ifort 14.0.1 编译:

module errormod

  type error_t
     character(len=:), allocatable :: message
   contains
     procedure write_error
     generic :: write(formatted) => write_error
  end type error_t

  logical debug_verbose

contains

  subroutine write_error(err, unit, iotype, v_list, iostat, iomsg)
    class(error_t), intent(in)  :: err
    integer, intent(in)  :: unit
    character(len=*), intent(in)  :: iotype
    integer, intent(in), dimension(:)  :: v_list
    integer, intent(out)  :: iostat
    character(len=*), intent(inout)  :: iomsg

    if (debug_verbose) then
       write(unit, '("Error: ", A)', iostat=iostat, iomsg=iomsg) err%message
    else
       write(unit, '()', advance='no')
    end if

  end subroutine write_error

end module errormod


program test

  use errormod

  implicit none

  type(error_t) error

  debug_verbose = .TRUE.
  error%message = "This error will be reported."
  write(*, '(dt)') error

  debug_verbose = .FALSE.
  error%message = "This error will not be reported."
  write(*, '(dt)') error

  debug_verbose = .TRUE.
  error%message = "This final error will also be reported."
  write(*, '(dt)') error

end program test

将出现第一条和第三条消息,但不会出现第二条消息。

于 2014-01-03T15:59:53.513 回答