9

我正在尝试将错误检查合并到我正在编写的纯程序中。我想要类似的东西:

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此处的固有类型),当出现错误时输出字符串?

4

2 回答 2

3

您不是第一个遇到这个问题的人,我很高兴地说,标准中的这个缺陷将在 Fortran 2015 中得到补救。如本文档所述(第 6 页,标题“已批准对标准的更改”), “应该取消对程序中语句出现的限制error stoppure” 。

Fortran 2008 标准error stop在一些新的并行计算特性的上下文中包含了该声明。它会发出错误信号并尽快停止所有进程。目前,过程中既不允许stoperror stop不允许语句pure,因为它们显然不是线程安全的。实际上,在发生内部错误的情况下,这是不必要的限制。

根据您的编译器,您可能需要耐心等待实现。我知道英特尔已经在他们的 ifort 编译器中实现了它。(“F2015:在 PURE/ELEMENTAL 程序中解除对 STOP 和 ERROR STOP 的限制”

选择

对于另一种方法,您可以看一下这个问题,但在您的情况下,这可能有点棘手,因为您必须更改do concurrent关键字,而不仅仅是pure.

(正确答案结束)

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

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

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

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

于 2016-06-22T14:28:42.827 回答
-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 建议的可能会更好——让过程返回一个状态,可能是一个逻辑值或整数,并让程序在每次调用过程后检查这个值。如果一切顺利,继续。否则,打印相关的错误消息。

欢迎评论。

于 2012-01-09T12:36:45.700 回答