为什么在每次子程序调用中计数器变量都意外增加?
Why is the counter variable unexpectedly increased in every subroutine call?
[社论:我读过 this question 但是(事后看来它最终是相关的,就像这里的每个问题都是相关的一样——即 "Why do computers malfunction?")答案不是回答我的问题。这个问题是在询问为什么标准机构将特定功能设计到语言中。而且,答案没有回答我的问题,即我在调试此问题时遗漏了什么。]
问题:为什么这个 Fortran 程序的输出 (ExhaustiveListing.f08 + unicodeSupport.f08) 表示 Fortran 的 DO WHILE 有重大错误?
这是输出,后面是环境描述,最后是两个相关文件的源代码:
意外输出
Hex is now: 2500H.
2500─
2501━
2502│
2503┃
2504┄
2505┅
2506┆
2507┇
2508┈
2509┉
250A┊
250B┋
250C┌
250D┍
250E┎
250F┏
Hex is now: 2510H.
Hex is now: 2520H.
Hex is now: 2530H.
Hex is now: 2540H.
Hex is now: 2550H.
Hex is now: 2560H.
Hex is now: 2570H.
RUN FINISHED; exit value 0; real time: 530ms; user: 0ms; system: 0ms
预期输出
我希望在每个“Hex is now: xxxxH”行之间有 16 行详细信息,例如打印在 2500H 和 2510H 行。
之前解决问题的尝试
这个程序是我在一个更大的项目中解决问题的尝试。那个项目有问题(一个这样的问题围绕着在 Fortran 中使用 Unicode),我创建了这个项目来隔离 Unicode 问题。起初,我将简单的 unicodeSupport 模块组合在与主程序相同的文件中。我将它删除到它自己的文件中。不,应该无关紧要——它不会影响结果。这个程序非常简单,我看不出我可能做错了什么。因此,我来到 SO 希望新的眼睛能发现我的错误。否则,是时候用 gFortran 提交错误报告了。
环境
我工作的环境是:
OS: Ubuntu 17.10
IDE: Netbeans 8.2
JDK:Oracle(内部版本 1.8.0_161-b12)
编译器:gFortran 7.2.0
编译器标志:-std=f2008ts -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans
theGeeko61:4 年在 BASIC、Pascal、FORTRAN、C、Prolog、C++、Java、许多其他方面的发展(按时间顺序排列学会了)
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
此处声明的变量counter
INTEGER :: hex, counter=0, point
通过在初始化行定义其值而拥有 save
属性。
第二次进入子程序时,它的值为16,因此不会有循环。
从声明行中删除=0
并写入
counter = 0
之后。
[社论:我读过 this question 但是(事后看来它最终是相关的,就像这里的每个问题都是相关的一样——即 "Why do computers malfunction?")答案不是回答我的问题。这个问题是在询问为什么标准机构将特定功能设计到语言中。而且,答案没有回答我的问题,即我在调试此问题时遗漏了什么。]
问题:为什么这个 Fortran 程序的输出 (ExhaustiveListing.f08 + unicodeSupport.f08) 表示 Fortran 的 DO WHILE 有重大错误?
这是输出,后面是环境描述,最后是两个相关文件的源代码:
意外输出
Hex is now: 2500H.
2500─
2501━
2502│
2503┃
2504┄
2505┅
2506┆
2507┇
2508┈
2509┉
250A┊
250B┋
250C┌
250D┍
250E┎
250F┏
Hex is now: 2510H.
Hex is now: 2520H.
Hex is now: 2530H.
Hex is now: 2540H.
Hex is now: 2550H.
Hex is now: 2560H.
Hex is now: 2570H.
RUN FINISHED; exit value 0; real time: 530ms; user: 0ms; system: 0ms
预期输出
我希望在每个“Hex is now: xxxxH”行之间有 16 行详细信息,例如打印在 2500H 和 2510H 行。
之前解决问题的尝试
这个程序是我在一个更大的项目中解决问题的尝试。那个项目有问题(一个这样的问题围绕着在 Fortran 中使用 Unicode),我创建了这个项目来隔离 Unicode 问题。起初,我将简单的 unicodeSupport 模块组合在与主程序相同的文件中。我将它删除到它自己的文件中。不,应该无关紧要——它不会影响结果。这个程序非常简单,我看不出我可能做错了什么。因此,我来到 SO 希望新的眼睛能发现我的错误。否则,是时候用 gFortran 提交错误报告了。
环境
我工作的环境是:
OS: Ubuntu 17.10
IDE: Netbeans 8.2
JDK:Oracle(内部版本 1.8.0_161-b12)
编译器:gFortran 7.2.0
编译器标志:-std=f2008ts -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans
theGeeko61:4 年在 BASIC、Pascal、FORTRAN、C、Prolog、C++、Java、许多其他方面的发展(按时间顺序排列学会了)
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
此处声明的变量counter
INTEGER :: hex, counter=0, point
通过在初始化行定义其值而拥有 save
属性。
第二次进入子程序时,它的值为16,因此不会有循环。
从声明行中删除=0
并写入
counter = 0
之后。