纯Fortran程序中的I / O.

时间:2012-01-07 03:50:33

标签: error-handling io fortran gfortran fortran95

我正在尝试将错误检查纳入我正在编写的纯过程中。我想要像:

pure real function func1(output_unit,a)
    implicit none
    integer :: a, output_unit

    if (a < 0) then
        write(output_unit,*) 'Error in function func1: argument must be a nonnegative integer. It is ', a
    else
    func1 = a/3

    endif
    return
end function func1

但是,不允许纯函数将IO语句赋予外部文件,因此我尝试将单元号传递给函数,例如output_unit = 6,这是默认输出。 gfortran仍然认为这是非法的。有没有解决的办法?是否可以使函数成为派生类型(而不是此处的内部类型real),在出现错误时输出字符串?

2 个答案:

答案 0 :(得分:3)

您不是第一个遇到此问题的人,我很高兴地说,标准中的这个缺陷将在Fortran 2015中得到纠正。如this document中所述(第6页,标题& #34;已批准更改标准&#34;),&#34;应删除error stop程序中pure语句外观的限制&#34;

Fortran 2008标准在一些新的并行计算功能的上下文中包含了error stop语句。它发出错误信号,并在可行的情况下尽快停止所有进程。目前,stop程序中不允许使用error stoppure语句,因为它们显然不是线程安全的。实际上,在发生内部错误的情况下,这是不必要的限制。

根据您的编译器,您可能需要耐心等待实施。我知道英特尔has implemented在他们的ifort编译器中。 (&#34; F2015:在PURE / ELEMENTAL程序中对STOP和ERROR STOP提升限制&#34;

替代

对于替代方法,您可以查看at this question,但在您的情况下,这可能会稍微复杂一些,因为您必须更改do concurrent关键字,而不仅仅是pure。< / p>

(正确答案结束)

如果弄脏手是一种选择......

与此同时,你可以做一些残酷的事情,比如

pure subroutine internal_error(error_msg)
    ! Try hard to produce a runtime error, regardless of compiler flags.
    ! This is useful in pure subprograms where you want to produce an error, 
    ! preferably with a traceback.
    ! 
    ! Though far from pretty, this solution contains all the ugliness in this 
    ! single subprogram.
    ! 
    ! TODO: replace with ERROR STOP when supported by compiler
    implicit none

    character(*), intent(in) :: error_msg

    integer, dimension(:), allocatable :: molested

    allocate(molested(2))
    allocate(molested(2))
    molested(3) = molested(4)
    molested(1) = -10
    molested(2) = sqrt(real(molested(1)))
    deallocate(molested)
    deallocate(molested)
    molested(3) = molested(-10)
end subroutine internal_error

如果有人问,你没有从我这里得到这个。

答案 1 :(得分:-1)

我自己找到了答案,详细here。它使用被认为是“过时”的东西,但仍然可以做到这一点;它被称为替代回报。将过程编写为子例程,因为它不适用于函数。

pure real subroutine procA(arg1)
    implicit none
    integer :: arg1

    if (arg < 0) then
        return 1 ! exit the function and go to the first label supplied
                 ! when function was called. Also return 2, 3 etc.
    else
        procA = ... ! whatever it should do under normal circumstances
    endif
endsubroutine procA

.... 

! later on, procedure is called
num = procA(a, *220)

220 write(6,*) 'Error with func1: you've probably supplied a negative argument'

什么可能更好的是eriktous建议的 - 获取程序返回状态,可能作为逻辑值或整数,并让程序每次调用该过程后检查该值。如果一切顺利,继续。否则,请打印相关的错误消息。

欢迎评论。