Fortran 2018+ 中过时的 DO 循环

pea*_*eze 5 fortran loops gfortran

我正在使用可能在最新版本的 gfortran 之前编写的源代码。我知道 DO、END DO 和 CONTINUE 的方式已更改,因此无法共享循环终止。有一个方便的链接在这里。问题是,我不知道该页面上的解释真正告诉我要做什么。如果我在新脚本中设置了一个非常基本的 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
Run Code Online (Sandbox Code Playgroud)

错误看起来像这样。对于出现的任何过时的 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)
Run Code Online (Sandbox Code Playgroud)

我想知道如何重新编写此代码块中的 DO 循环,以便我可以浏览并更新此源代码。如果相关,我在 Cygwin 上运行 GFortran9.3.0。

jac*_*cob 7

正如警告消息所说,所有DO循环都应以END DO或终止CONTINUE,例如:

            DO 20 IV = 1, 100
            LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
20          CONTINUE
Run Code Online (Sandbox Code Playgroud)

旧版本的 Fortran 允许程序员删除终止行,导致较短的

            DO 20 IV = 1, 100
20          LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
Run Code Online (Sandbox Code Playgroud)

但是,这两个代码在功能上是等效的。您可以使用一些简单的循环自行测试。


fra*_*lus 6

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

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

非块 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))
Run Code Online (Sandbox Code Playgroud)

使用未标记的形式

DO II = I1, I2
   IW = ICN(II)
   IF (NUMB(IW)==0) GOTO 70
   LOWL(IV) = MIN(LOWL(IV),LOWL(IW))
END DO
Run Code Online (Sandbox Code Playgroud)

或标签形式

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
Run Code Online (Sandbox Code Playgroud)

我相信很多人会更喜欢无标签的形式。事实上,标记形式在 Fortran 2018 中已经过时。

对于非块 DO 构造,其中终止动作语句也是go to我们重写的目标,以便go to指向(标记的)语句的点被拉入循环。我们还可以重写共享终止操作语句的非块 DO 构造。