Error handling 纯Fortran程序中的I/O
我试图将错误检查纳入我正在编写的纯过程中。我想要一些像:Error handling 纯Fortran程序中的I/O,error-handling,io,fortran,gfortran,fortran95,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
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
纯实函数func1(输出单位a)
隐式无
整数::a,输出单位
如果(a<0),则
函数func1中的write(output_unit,*)”错误:参数必须是非负整数。这是一个
其他的
func1=a/3
恩迪夫
返回
结束函数func1
但是,纯函数不允许将IO语句传递到外部文件,因此我尝试将单元号传递给函数,例如,
output\u unit=6
,这是默认输出。格夫特兰仍然认为这是非法的。有办法解决这个问题吗?有没有可能使函数成为一个派生类型(而不是这里的内在类型real
),在出现错误时输出一个字符串?我自己找到了一个答案,非常详细。它使用了被认为是“过时”的东西,但仍然起作用;这叫做交替返回。将该过程作为子例程编写,因为它不适用于函数
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'
纯实数子程序procA(arg1)
隐式无
整数::arg1
如果(arg<0),则
返回1!退出函数并转到提供的第一个标签
! 当函数被调用时。还返回2、3等。
其他的
procA=!无论它在正常情况下应该做什么
恩迪夫
endsubroutine程序
....
! 稍后,调用该过程
num=procA(a,*220)
220写入(6,*)'func1错误:您可能提供了一个否定参数'
更好的可能是eriktous所建议的——让过程返回一个状态,可能是一个逻辑值或一个整数,让程序在每次调用过程后检查这个值。如果一切顺利,继续。否则,打印相关的错误消息
欢迎评论。您不是第一个遇到此问题的人,我很高兴地说,标准中的此缺陷将在Fortran 2015中得到修复。如(第6页标题“已批准的标准变更”)所述,“应取消对
纯程序中出现错误停止
语句的限制”
Fortran 2008标准在一些新的并行计算特性的上下文中包含了错误停止
语句。它发出错误信号,并使所有进程尽快停止。目前,pure
过程中既不允许使用stop
语句,也不允许使用error stop
语句,因为它们显然不是线程安全的。实际上,在发生内部错误的情况下,这是不必要的限制
根据编译器的不同,您可能需要耐心等待实现。我知道英特尔在他们的ifort编译器中提供了它。(“F2015:纯/基本程序中停止和错误停止的提升限制”)
可供替代的
对于另一种方法,您可以看一看,不过在您的情况下,这可能有点棘手,因为您必须更改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
如果有人问,您不是从我这里得到的。从技术上讲,“纯”过程不会以任何方式修改其环境或任何操作数。所以它不应该打印到屏幕上?它是否可以打印到主程序可以访问并打印到屏幕的内部字符串?不过,这太迂回了。@SamuelTan-Nope-no纯内存中没有任何类型的I/O。简言之,它不改变任何东西(变量、局部或全局)、不保存,也不I/O任何东西(将它所做的事情列成一个列表会更容易:\…;)通常绕过这些限制的方法是将函数转换为子例程,并添加一个额外的参数来返回状态(此参数可以使用派生类型,以返回错误代码和错误文本)。@HotLicks。我在do concurrent
块中使用此函数,因此它必须是纯的(我必须显式地将pure
放在前面,否则编译器会抱怨).Argh!请不要使用此选项。将其标记为“过时”是有原因的。当前标准建议以下选项作为替代选项(基本上与我的建议相同):返回时,在SELECT CASE构造中使用的返回代码也可以达到同样的效果。
残酷的子例程是不必要的复杂。你也可以只编写一个外部子例程,然后放在一个纯粹的接口中。非常简单。这符合标准吗?当然不是,但我不认为是考虑到它所做的是有害的。当它中止程序时,它不会以任何方式破坏其余的运行。标准(尤其是95标准)也不会指定当你将一个负数的平方根设为平方根时会发生什么。在符合IEEE标准的Fortran 2003 CPU中,只有当你确实设置了正确的标志以启用对IEEE异常的暂停时,你才有一些保证。但人们通常不希望在任何地方都这样。我当然不会在运行我的主代码时暂停浮点异常。