Fortran 2018+中过时的DO循环

10

我正在使用一个可能是在最近版本的gfortran之前编写的源代码。我知道DO,END DO和CONTINUE的方式已经改变,因此不能共享循环终止。这里有一个方便的链接here。问题是,我不知道解释告诉我要在该页面上做什么。如果我在新脚本中设置了一个非常基本的DO循环,则可以编译而不出错。我不确定如何反向工程化以找到问题所在。

以下是代码中返回错误消息的部分。

              DO 20 II = I1, I2
              IW = ICN(II)
!             Has node iw been on stack already?
              IF (NUMB(IW)==0) GOTO 70
!             Update value of LOWL(IV) if necessary.
20          LOWL(IV) = MIN(LOWL(IV),LOWL(IW))

!           There are no more edges leaving node IV.
            ARP(IV) = -1
!           Is node IV the root of a block.
30          IF (LOWL(IV)<NUMB(IV)) GOTO 60

!           Order nodes in a block.
            NUM = NUM + 1
            IST1 = N + 1 - IST
            LCNT = ICNT + 1
!           Peel block off the top of the stack starting at the
!           top and working down to the root of the block.
            DO STP = IST1, N
              IW = IB(STP)
              LOWL(IW) = N + 1
              ICNT = ICNT + 1
              NUMB(IW) = ICNT
              IF (IW==IV) GOTO 50
            END DO

错误看起来像这样。基本上,对于任何过时的DO循环出现时都会重复相同的错误,并且编译时只会出现这种类型的错误。

dvode_f90_m.f90:15865:45:

15865 | 20          LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
      |                                             1
Warning: Fortran 2018 deleted feature: DO termination statement which is not END DO or CONTINUE with label 20 at (1)

我想知道如何重写这段代码中的DO循环,以便我可以浏览并更新这个源代码。如果有相关信息,我正在Cygwin上运行GFortran9.3.0。


4
如果你仔细阅读gfortran的提示信息,你会发现你收到了一个警告。你没有收到一个错误。修复问题的一种方法是从do-loop和标记语句中删除20,并在标记语句后添加 end do - evets
2个回答

12

正如警告信息所说,所有的DO循环都应该以END DOCONTINUE结束,例如:

            DO 20 IV = 1, 100
            LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
20          CONTINUE

Fortran的旧版本允许程序员省略结束行,导致更短的代码。

            DO 20 IV = 1, 100
20          LOWL(IV) = MIN(LOWL(IV),LOWL(IW))

然而,这两个代码在功能上是等价的。您可以通过一些简单的循环自行测试。


非常感谢您提供的简明扼要的解释。 - peasqueeze
只是一个小修正。没有错误信息。那只是一个警告。这两者是完全不同的东西。 - evets
@evets 你是对的。我更正了答案的措辞。 - jacob

11
在Fortran 2018之前,DO结构有两种形式:块DO结构和非块DO结构。Fortran 2018删除了非块DO结构,并且您的编译器警告与使用此已删除形式有关。共享终止是一个稍微不同的问题。
Fortran 2018中的DO结构(先前语言标准中的块DO结构)要求终止语句为end do语句或(带标签的)continue语句。(如果DO结构是带标签的DO结构,例如do 1 ...,则必须标记end do语句。)
非块DO结构的限制要少得多,并允许许多其他语句(操作语句)成为DO结构的标记结尾。但是,标记终止语句始终在DO结构的范围内(因此将在每次迭代中执行)。赋值语句(如问题中的语句)是一种操作语句。
这意味着您可以现代化问题的(Fortran 2008非块)DO结构(为清晰起见,删除注释并更改为自由格式源代码)。
DO 20 II = I1, I2
   IW = ICN(II)
   IF (NUMB(IW)==0) GOTO 70
20 LOWL(IV) = MIN(LOWL(IV),LOWL(IW))

使用未标记的表单

DO II = I1, I2
   IW = ICN(II)
   IF (NUMB(IW)==0) GOTO 70
   LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
END DO

{{标签形式}}或{{标记形式}}
DO 20 II = I1, I2
   IW = ICN(II)
   IF (NUMB(IW)==0) GOTO 70
   LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
20 END DO ! OR CONTINUE

我确定很多人更喜欢没有标签的形式。实际上,在Fortran 2018中,带标签的形式已经过时了。
对于非块DO结构,其中终止操作语句也是go to的目标,我们重写它,使go to指向被拉入循环的(带标签的)语句。我们还可以重写非块DO结构,这些结构共享终止操作语句。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接