为什么在每个子程序调用中计数器变量意外增加?

时间:2018-03-26 07:36:15

标签: unicode fortran do-while gfortran

[编者按:我已经阅读了this question但是(事后看来,它最终的相关方式与此处的每个问题都相关 - 即“为什么计算机出现故障?”)答案不是回答我的问题。这个问题是为什么标准机构在语言中设计了一个特定的功能。并且,答案并没有回答我的问题,即在调试此问题时我错过了什么。]

问题:为什么下面显示的此Fortran程序( ExhaustiveListing.f08 + unicodeSupport.f08 )的输出表明Fortran的DO WHILE有一个主要的错误?

这是输出,然后是环境描述,最后是两个文件的源代码:

意外输出

  

Hex现在: 2500H
  2500─
  2501━
  2502│
  2503┃
  2504┄
  2505┅
  2506┆
  2507┇
  2508┈
  2509┉
  250A┊
  250B┋
  250C┌
  250D┍
  250E┎
  250F┏
  Hex现在是: 2510H   Hex现在是: 2520H   Hex现在是: 2530H   Hex现在是: 2540H   Hex现在是: 2550H   Hex现在是: 2560H   Hex现在是: 2570H   
  跑完了;退出值0;实时:530ms;用户:0ms; system:0ms

预期输出

我希望在每个“ Hex现在: xxxxH ”之间有16行详细信息,例如在 2500H 之间打印的行 2510H 行。

以前尝试解决问题

这个程序是我尝试在更大的项目中解决问题。遇到该项目的问题(围绕在Fortran中使用Unicode的一个问题),我创建了这个项目以隔离Unicode问题。起初,我将简单的unicodeSupport模块与主程序放在同一个文件中。我把它删除到自己的文件中。不,它应该无关紧要 - 它不会影响结果。这个程序非常简单,我看不出任何我可能做错的事情。因此,我来​​到SO,希望新的眼睛发现我的错误。另外,是时候用gFortran提交bug报告了。

环境

我所处的环境是:
操作系统 Ubuntu 17.10 IDE Netbeans 8.2 JDK Oracle(内部版本1.8.0_161-b12) COMPILER gFortran 7.2.0 编译器标记 -std = f2008ts -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans theGeeko61 在BASIC,Pascal,FORTRAN,C,Prolog,C ++,Java等许多其他项目开发了40年(按照我学习它们的顺序按时间顺序排序)

ExhaustiveListing.f08

! File:   ExhaustiveListing.f08
! Author: geeko
!
! Created on March 25, 2018, 7:05 PM
!
! ☐ U2610 ☑ U2611 ☒ U2612
! Use above symbols for indicating items to
! be tested (☐), and items which have either
! passed (☑) or failed (☒) testing.
!
SUBROUTINE displayLine(hex)
    USE unicodeSupport
    IMPLICIT NONE
    INTEGER :: hex, counter=0, point

    DO WHILE (counter < 16)
        point = hex+counter
        WRITE(*,'(Z4.4,A)') point, CHAR(INT(point), ucs4)
        counter = counter+1
    END DO
END SUBROUTINE

PROGRAM ExhaustiveListingOfUnicodeBoxDrawingChars ! ☒
    USE ISO_FORTRAN_ENV
    USE unicodeSupport
!!!!!USE testUnicodeSupport         ! ☑
    IMPLICIT NONE
    INTEGER  :: hex

    open(output_unit, encoding='UTF-8')

    hex = 9472
    DO WHILE(hex<9600)
        PRINT '(A,Z4.4,A)', "Hex is now: ", hex, "H."
        CALL displayLine(hex)   ! ☒
        hex = hex+16
    END DO

!!!!CALL performTest()              ! ☑
END PROGRAM ExhaustiveListingOfUnicodeBoxDrawingChars

unicodeSupport.f08

! File:   unicodeSupport.f08
! Author: geeko
!
! Created on March 25, 2018, 10:09 PM
!

MODULE unicodeSupport
    INTEGER, PARAMETER  :: ASCII = SELECTED_CHAR_KIND('ASCII')
    INTEGER, PARAMETER  :: UCS4 = SELECTED_CHAR_KIND('ISO_10646')
END MODULE unicodeSupport

1 个答案:

答案 0 :(得分:3)

此处声明的变量counter

INTEGER :: hex, counter=0, point

凭借在初始化行上定义其值来拥有save属性。

第二次进入子程序时,其值将为16,因此不会有循环。

从声明行中删除=0并写入

counter = 0

之后。