3

使用 gfortran 在 Fortran 90 中编写和调用纯子例程时,如何找出编译器发出此错误的原因?

Error: Subroutine call to XXXX at (1) is not PURE

我将尝试尽可能具体地提出我的问题,同时又足够笼统以对其他人有用,因此我将避免粘贴我的实际代码,而是会勾勒出发生的事情。

我知道 Fortran 90 中有关于纯过程的各种规则,我认为这些规则基本上可以归结为不允许函数或子例程中的副作用,并且不允许更改用intent(in). 我有一系列最初没有声明为纯的子程序,其参数没有声明意图,但仍然没有执行副作用。首先,我将所有参数声明更改为具有明确声明的意图,即inoutinout。然后,我将所有子例程声明为PURE. 当然,第一次尝试时出现了很多错误,但是编译器告诉我错误是什么(例如intent(in)正在修改某某参数),所以我一个一个地修复了它们。

但是,这些程序之间存在调用,所以现在我仍然收到许多如上所示形式的错误:Subroutine call to XXXX at (1) is not PURE. 我不明白为什么这个电话不纯。我已经做了所有我能想到的让 XXXX 纯净的事情,但编译器仍然认为它不是。

所以我的问题——改写——是:我如何让 gfortran 告诉我为什么它认为 XXXX 不纯?

4

4 回答 4

3

“将我正在处理的库中的所有 PURE 子例程放入一个 MODULE(我的客户端代码然后使用它)。......不知道为什么......,但在这样做之后会有更多有用的错误消息出现了,这让我能够追踪剩余的杂质。”

将子例程放入模块中,然后使用它们使接口变得明确。这允许编译器检查调用和子例程之间的一致性,并在存在差异时生成错误消息。非常有用,因此将子例程和函数放入模块中是一种很好的做法。

使接口显式的另一种方法是编写接口,但这是额外的工作和出错的额外步骤。

对纯子例程/函数有很多要求。如果您有 Metcalf、Reid 和 Cohen 解释的 Fortran 95/2003,请参阅第 6.10 节。例如,没有“保存”变量,没有停止语句,没有外部文件上的 IO,......

您还可以尝试其他编译器,看看他们的错误信息是否更有帮助。其他免费的,取决于操作系统,包括 g95 和 Sun Studio。

于 2009-10-11T16:10:03.327 回答
1

我会尽量在回答中更清楚地说明我的问题。由于这些原因,我不愿意发布我的代码。

  1. 我不希望其他人为我调试我的代码。问的太多了。
  2. 我希望我的问题及其答案更笼统。
  3. 似乎 gfortran 告诉我我的子程序不是 PURE,但它并没有告诉我为什么它认为它们不纯。

所以我希望找到的不是如何修复我的代码并使程序成为 PURE,而是找出如何从 gfortran 中获取更多有用的信息,以帮助我修复我的代码。

我做的两件事帮助实现了这些目标。当然,您的结果可能会有所不同。

  1. 将此标志添加到 gfortran 命令行: -fmax-errors=100 当然,我之前已经这样做了,但它似乎仍然没有告诉我我需要知道什么。
  2. 将我正在处理的库中的所有 PURE 子例程放入一个 MODULE(然后我的客户端代码使用它)。由于这个库的祖先是 Fortran77,所以最初情况并非如此。不知道为什么(这就是为什么我强调“你的结果可能会有所不同”),但在这样做之后出现了更有用的错误消息,这使我能够追踪剩余的杂质。

这是一个模糊的问题,我知道,我不确定它会有多大用处。不过,感谢所有阅读、评论和添加答案的人。

于 2009-10-02T17:36:34.593 回答
0

可能是因为它没有标记为 PURE。子例程是纯的这一事实与其参数无关,而是与它被声明为 PURE 的事实有关。(当然,一旦声明为纯,你对参数所做的事情就会起作用并被检查。)

于 2009-09-30T17:23:57.757 回答
0

我是 Fortran 初学者,上周我读到了书中关于 Fortran 程序的章节。可能是我不对,但是......所以如果你原谅我的英语有一些评论:

  1. 将子例程声明为纯的不是一种好风格。建议使用函数
  2. Fortran 95 标准中引入了纯过程。不在 Fortran 90 中。
  3. 您的问题可能来自(Fortran 2003 标准)中的 C1270 项,内容如下:

如果在要求它是纯的的上下文中使用既不是内在过程也不是语句函数的过程,则其接口在该使用范围内应是显式的。接口应规定程序是纯的。

我希望这是有用的信息。

于 2009-10-06T09:26:15.613 回答