纯 Fortran 过程中的 I/O
我正在尝试将错误检查合并到我正在编写的纯过程中。我想要这样的东西:
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
),在出现错误时输出字符串?
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
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不是第一个遇到此问题的人,我很高兴地说标准中的此缺陷将在 Fortran 2015 中得到纠正。如 本文档(第 6 页,标题“已批准对标准的更改”),“对外观的限制应删除
pure
过程中的error stop
语句”。Fortran 2008 标准在一些新的并行计算功能中包含了
error stop
语句。它发出错误信号并在可行的情况下尽快停止所有进程。目前,pure
过程中不允许使用stop
和error stop
语句,因为它们显然不是线程安全的。实际上,在发生内部错误的情况下,这是不必要的限制。根据您的编译器,您可能需要耐心等待实现。我知道英特尔 已在其 ifort 编译器中实现了。 (“F2015:在 PURE/ELEMENTAL 过程中解除对 STOP 和 ERROR STOP 的限制”)
替代方法
对于替代方法,您可以查看 在这个问题,尽管在你的情况下,这可能有点棘手,因为你必须更改
do并发
关键字,而不仅仅是pure
。(正确答案结束)
如果弄脏手是一种选择......
与此同时,你可以做一些残酷的事情,比如
如果有人问,你没有从我这里得到这个。
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 apure
procedure should be removed".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, neitherstop
norerror stop
statements are allowed inpure
procedures, because they're obviously not thread-safe. In practice this is unnecessarily restrictive in cases where an internal error occurs.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")
alternative
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 justpure
.(end of proper answer)
if getting dirty hands is an option ...
In the meantime you could do something brutal like
Should anyone ask, you didn't get this from me.
我自己找到了答案,详细此处。它使用了被认为“过时”的东西,但仍然有效;这称为交替返回。将过程编写为子例程,因为它不适用于函数。
eriktous 所建议的可能会更好——让过程返回一个状态,可能是一个逻辑值或一个整数,并让程序在每次调用该过程后检查这个值。如果一切顺利,继续。否则,打印相关错误信息。
欢迎评论。
I've found an answer myself, detailed here. It uses what is considered "obsolescent", but still does the trick; it is called alternate return. Write the procedure as a subroutine as it doesn't work on functions.
What would probably be better is what eriktous suggested--get the procedure to return a status, perhaps as a logical value or an integer, and get the program to check this value every time after it calls the procedure. If all's well, carry on. Otherwise, print a relevant error message.
Comments welcome.