纯Fortran过程中的I / O [英] I/O in pure Fortran procedures
问题描述
我正在尝试将错误检查合并到我编写的纯过程中。我想要类似的东西:
I'm trying to incorporate error checking within a pure procedure I am writing. I would like something like:
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
),该类型在出现错误时会输出字符串?
However, pure functions are not allowed to have IO statements to external files, so I tried passing a unit number to the function, e.g. output_unit = 6
, which is the default output. gfortran still regards this as illegal. Is there a way around this? Is it possible to make the function a derived type (instead of intrinsic type real
here) which outputs a string when there is an error?
推荐答案
您不是第一个遇到此问题的人,我很高兴地说,该标准中的此缺陷将在Fortran 2015中得到解决。 本文档(第6页,标题为批准对标准进行更改), 应该删除在纯
过程中出现错误停止
语句的限制 。
You are not the first person to have this problem, and I'm happy to say that this flaw in the standard will be remedied in Fortran 2015. As stated in this document (page 6, header "Approved changes to the standard"), "the restriction on the appearance of an error stop
statement in a pure
procedure should be removed".
Fortran 2008标准在一些新的并行计算功能的上下文中包括了 error stop
语句。它会发出错误信号,并使所有进程在可行的情况下尽快停止。当前,纯
stop 和 error stop
语句>过程,因为它们显然不是线程安全的。实际上,这在发生内部错误的情况下是不必要的限制。
The Fortran 2008 standard included the error stop
statement in the context of some new parallel computing features. It signals an error and makes all processes stop as soon as is practicable. Currently, neither stop
nor error stop
statements are allowed in pure
procedures, because they're obviously not thread-safe. In practice this is unnecessarily restrictive in cases where an internal error occurs.
根据您的编译器,您可能必须耐心等待实现。我知道英特尔已在其ifort编译器中实现了。 ( F2015:在PURE / ELEMENTAL过程中对STOP和ERROR STOP的解除限制 )
Depending on your compiler, you may have to wait patiently for the implementation. I know that Intel has implemented it in their ifort compiler. ("F2015: Lift restriction on STOP and ERROR STOP in PURE/ELEMENTAL procedures")
对于另一种方法,您可以看看这个问题,尽管在您这种情况下,这可能会有些棘手,因为您必须更改并发
关键字,而不仅仅是纯
。
For an alternative approach, you could have a look at this question, though in you case this is probably slightly trickier as you have to change the do concurrent
keyword, not just pure
.
与此同时,您可以做一些残酷的事情
In the meantime you could do something brutal like
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
有人问,您没有得到这个从我这里来。
Should anyone ask, you didn't get this from me.
这篇关于纯Fortran过程中的I / O的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!