使用 gfortran 在 Fortran 90 中编写和调用纯子例程
当使用 gfortran 在 Fortran 90 中编写和调用纯子例程时,如何找出编译器发出此错误的原因?
Error: Subroutine call to XXXX at (1) is not PURE
我将尝试尽可能具体地提出我的问题,同时足够笼统以对其他人有用,因此我将避免粘贴我的实际代码,而是会概述所发生的情况。
我知道 Fortran 90 中有关于纯过程的各种规则,我认为这些规则基本上可以归结为不允许函数或子例程中出现副作用,并且不允许更改使用 intent(in)
。我有一系列子例程,它们最初没有声明为纯子例程,其参数没有声明意图,但仍然没有执行副作用。首先,我将所有参数声明更改为具有显式声明的意图,in
、out
或 inout
。然后,我将所有子例程声明为PURE
。当然,第一次尝试时出现了很多错误,但是编译器告诉我错误是什么(例如,intent(in)
的此类参数正在被修改),所以逐一-一个我把它们全部修好了。
然而,这些过程之间存在调用,因此现在我仍然收到许多如上所示形式的错误:Subroutine call to XXXX at (1) is not PURE
。我不明白的是为什么这个调用不是纯粹的。我已尽一切努力使 XXXX 变得纯净,但编译器仍然认为它不是。
所以我的问题——重新表述——是:我如何让 gfortran 告诉我为什么它认为 XXXX 不是纯的?
When writing and calling pure subroutines in Fortran 90 using gfortran, how do I find out why the compiler emits this error?
Error: Subroutine call to XXXX at (1) is not PURE
I'll try to pose my question as specifically as I can while at the same time being general enough to be useful to others, so I'll avoid pasting in my actual code and instead will sketch what happened.
I understand there are various rules about pure procedures in Fortran 90, which I think basically boil down to not permitting side-effects in either functions or subroutines, and not permitting changes to subroutine parameters declared with intent(in)
. I've a series of subroutines which initially were not declared to be pure, and whose parameters didn't have declared intent, but which nevertheless didn't perform side-effects. First, I changed all parameter declarations to have explicitly-declared intent, either in
, out
, or inout
. Then, I declared all the subroutines to be PURE
. Naturally, many errors occurred on the first attempt, but the compiler told me what the errors were (such-and-such parameter with intent(in)
is being modified, for example), so one-by-one I fixed them all.
There are calls among these procedures, however, and so now I still get many errors of the form shown above: Subroutine call to XXXX at (1) is not PURE
. What I don't understand is why the call is not pure. I've done everything I can think of to make XXXX pure, but the compiler still thinks it isn't.
So my question --rephrased-- is: how do I get gfortran to tell me WHY it thinks XXXX is not pure?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
“将我正在开发的库中的所有 PURE 子例程放入模块中(然后我的客户端代码使用它)。……不知道为什么……,但在执行此操作后会出现更有用的错误消息出现了,这让我能够追踪到剩余的杂质。”
将子例程放入模块中然后使用它们可以使接口显式化。这允许编译器检查调用和子例程之间的一致性,并在存在差异时生成错误消息。非常有用,因此将子例程和函数放入模块中是很好的做法。
使接口显式化的另一种方法是编写接口,但这是额外的工作,并且是一个容易出错的额外步骤。
关于纯子例程/函数的要求有一长串。如果您有 Metcalf、Reid 和 Cohen 的 Fortran 95/2003 解释,请参阅第 6.10 节。例如,没有“保存”变量,没有停止语句,外部文件上没有 IO,...
您还可以尝试其他编译器,看看它们的错误消息是否更有帮助。其他免费的(取决于操作系统)包括 g95 和 Sun Studio。
"Placed all the PURE subroutines in the library I'm working on, into a MODULE (which my client code then USEd). ...... Not sure why ....., but after doing this more useful error messages appeared which allowed me to track down the remaining impurities."
Placing the subroutines into a module and then using them makes the interface explicit. This allows the compiler to check agreement between the call and the subroutine and generate error messages if there is a discrepancy. Very useful, so placing subroutines and functions into modules good practice.
The other way of making an interface explicit is to write an interface, but that is extra work and an extra step to get wrong.
There is a long list of requirements on pure subroutines/functions. If you have Fortran 95/2003 Explained by Metcalf, Reid and Cohen, see section 6.10. For example, no "save" variables, no stop statement, no IO on external file, ...
You can also try other compilers to see if their error message is more helpful. Other free ones, depending on OS, include g95 and Sun Studio.
我会尽力在回答中更清楚地说明我的问题。由于这些原因,我不愿意发布我的代码。
所以我希望找到的不是如何修复我的代码并使程序变得纯粹,而是找出如何从 gfortran 中获取更多有用的信息,以帮助我修复我的代码。
我所做的两件事帮助实现了这些目标。当然,您的结果可能会有所不同。
当然,我很早就这样做了,但它似乎仍然没有告诉我我需要知道什么。
我知道这是一个模糊的问题,而且我不确定它会有多大用处。尽管如此,还是感谢所有阅读、评论和添加答案的人。
I'll try to be more clear about my question in my answer. I was reluctant to post my code for these reasons.
So I hoped to find out, not how to fix my code and make the procedures PURE, but rather to find out how to coax more useful information from gfortran, in order to help me fix my code.
Two things that I did helped fulfill these goals. Of course, your results may vary.
Of course, I'd done that earlier, but it still seemed not to tell me what I needed to know.
It's kind of a nebulous question, I know, and I'm not sure how useful it will be. Still, thanks to everyone who read, commented on, and added answer(s).
可能是因为它没有标记为 PURE。子例程是纯粹的这一事实与它的参数做什么或不做什么无关,而是与它被声明为 PURE 的事实有关。 (当然,一旦声明为纯的,您对参数所做的操作就会发挥作用并受到检查。)
Probably because it's not marked as PURE. The fact that a subroutine is pure is not related to what it does or not with its arguments, but to the fact that it's declared as PURE. (Of course, once declared as pure, what you do with the arguments comes into play and is checked.)
我是 Fortran 初学者,上周我在书中读到了有关 Fortran 过程的章节。也许我是不对的,但是......所以,如果你能原谅我的英语,有一些评论:
我希望这是有用的信息。
I am Fortran beginner and last week I reached chapter about Fortran procedures in my book. May be I'm not right but... So if you will excuse my English there are some remarks:
I hope that it is useful information.