使用 gfortran 在 Fortran 90 中编写和调用纯子例程

发布于 2024-08-06 10:13:30 字数 764 浏览 3 评论 0原文

当使用 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 不是纯的?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

山人契 2024-08-13 10:13:30

“将我正在开发的库中的所有 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.

离旧人 2024-08-13 10:13:30

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

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

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

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

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

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

I'll try to be more clear about my question in my answer. I was reluctant to post my code for these reasons.

  1. I don't expect other people to debug my code for me. That's way too much to ask.
  2. I wanted my question and its answer(s) to be more general.
  3. It seemed gfortran was telling me my subroutines were not PURE, but it wasn't telling me WHY it considered them not to be pure.

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.

  1. Added this flag to the gfortran command-line: -fmax-errors=100
    Of course, I'd done that earlier, but it still seemed not to tell me what I needed to know.
  2. Placed all the PURE subroutines in the library I'm working on, into a MODULE (which my client code then USEd). Since this library's ancestry is as Fortran77, originally, this was not the case. Not sure why (which is why I stress that "your results may vary"), but after doing this more useful error messages appeared which allowed me to track down the remaining impurities.

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).

咆哮 2024-08-13 10:13:30

可能是因为它没有标记为 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.)

冬天旳寂寞 2024-08-13 10:13:30

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

  1. 声明纯子例程不是一个好的风格。对于函数来说是可取的。
  2. Fortran 95 标准中引入了纯过程。 Fortran 90 中没有。
  3. 您的问题可能来自(Fortran 2003 标准)中的 C1270 项,其内容如下:

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

我希望这是有用的信息。

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:

  1. It's not good style to declare subroutines pure. It's advisable for functions.
  2. Pure procedures were introduced in Fortran 95 standard. Not in Fortran 90.
  3. You problem probably arises from item C1270 in (Fortran 2003 Standard) which read as follows:

If a procedure that is neither an intrinsic procedure nor a statement function is used in a context that requires it to be pure, then its interface shall be explicit in the scope of that use. The interface shall specify that the procedure is pure.

I hope that it is useful information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文