Fortran 2018+中过时的DO循环

问题描述

我正在使用的源代码可能是在最新版本的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。

解决方法

如警告消息所述,所有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))

但是,这两个代码在功能上是等效的。您可以通过一些琐碎的循环自己进行测试。

,

在Fortran 2018之前,DO构造有两种形式:块DO构造非块DO构造。 Fortran 2018删除了非阻塞DO构造,并且编译器发出的警告与使用此删除形式有关。共享终止是一个稍微不同的问题。

Fortran 2018中的DO构造(以前的语言标准中的块DO构造)要求终止语句为end do语句或(标记为)continue语句。 (如果DO构造是带有标签的DO构造,例如end do,则必须标记do 1 ...语句。)

非阻塞DO构造的限制要少得多,并允许许多其他语句( action 语句)成为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,LOWL(IW))
20 END DO ! OR CONTINUE

我敢肯定,很多人会喜欢没有标签的表格。确实,该标签形式在Fortran 2018中已经过时。