错误:逻辑运算符(1)的操作数为整数(4)/Hollerith [英] Error: Operands of logical operator '.eq.' at (1) are INTEGER(4)/HOLLERITH
问题描述
我是Fortran新手。所以我需要帮助。我在SuSE上使用gfortran编译代码,收到以下错误:
200 IF ( ID .EQ. 4HEOT ) GO TO 20
1
Error: Operands of logical operator '.eq.' at (1) are INTEGER(4)/HOLLERITH
代码的主文件附加在下面的链接中,在1818行显示错误。
我的文件链接是:https://files.engineering.com/getfile.aspx?folder=cd6961f3-d38b-4e61-a43d-269fa18c7d11&file=sfeng.f
如何修复此问题?
为了简化/最小化示例,我在此处添加了代码:
SUBROUTINE CDRD ( II )
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
c ohad 15/7/08
c IMPLICIT INTEGER*8 (I-N)
IMPLICIT INTEGER*4 (I-N)
C*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=C
C THIS SUBROUTINE READS PROPULSION SYSTEM DRAG DATA. C
C C
C USE NON-ZERO "II" TO WRITE TABLE DATA. C
C*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=C
CHARACTER*80 TITLE, CDFILE
DIMENSION A(100),IREP(30),IDD(4)
COMMON /UNITS / IU5, IU6, IU7, IU8, IU9, IU16, IU17, IU18
COMMON /CYUNIT/ IU3, IU4, IU10, IU11, IU12, IU13, IU14, IU15
COMMON /CYICOM/ IENG, IPRINT, NPRINT, NPDRY, NPAB, NITMAX,
1 IVAT, LIMCD
COMMON /CDSIZE/ CDNOZ(5000)
COMMON /ICDTAB/ ICDDAT(10), NTBL
COMMON /CDLOC/ LOCCD(5)
COMMON /CDFIL / CDFILE, A10, A9REF, A10REF, XNOZ, XNREF, RCRV,
1 NAB, NABREF
C======================================================================C
IU12 = 12
IUNIT = IU12
OPEN (UNIT=IUNIT, FILE=CDFILE, STATUS='OLD', ERR=9992)
REWIND (IUNIT)
NTBL = 0
NMAX = 5000
MR = 0
IF ( NTBL .EQ. 0 ) THEN
LOC = 1
DO 10 M = 1,NMAX
10 CDNOZ(M) = 0.
ENDIF
20 READ (IU12, 5000, END=400, ERR=6666 ) IP, ITABNO, TITLE
30 IF(ITABNO .EQ. 0) THEN
NREM = NMAX-LOC
IF ( II .GT. 0 ) THEN
WRITE(IU6,5010) NTBL
WRITE(IU6,5020) (N, ICDDAT(N), LOCCD(N), N = 1,NTBL)
WRITE(IU6,5030) NMAX, NREM
ENDIF
IF( MR .GT. 0 ) WRITE(IU6,5040) (IREP(IQ), IQ = 1,MR)
RETURN
ELSE
NTBL = NTBL+1
ICDDAT(NTBL) = ITABNO
LOCCD(NTBL) = LOC
IF ( NTBL .GT. 1 ) THEN
DO 40 I = 2,NTBL
IF ( ITABNO .EQ. ICDDAT(I-1) ) GO TO 50
40 CONTINUE
GO TO 150
50 MLOC = LOCCD(I-1)
ILOC = MLOC
LOCCD(I-1) = LOC
NTBL = NTBL - 1
MR = MR + 1
IREP(MR) = ITABNO
LIBLOC = 100000
DO 60 IRK = 1,NTBL
LIBRA = LOCCD(IRK)
IF ( (LIBRA .GE. MLOC) .AND. (LIBRA .LT. LIBLOC) )
* LIBLOC = LIBRA
60 CONTINUE
LEO = LIBLOC - MLOC
IF ( LEO .NE. 0 ) THEN
IZAR = LOC - 1
DO 70 I = LIBLOC,IZAR
CDNOZ(MLOC) = CDNOZ(I)
MLOC = MLOC + 1
70 CONTINUE
DO 80 I = 1,NTBL
LLOC = LOCCD(I)
IF ( LLOC .GT. ILOC ) LOCCD(I) = LLOC - LEO
80 CONTINUE
ENDIF
DO 90 I = MLOC,LOC
90 CDNOZ(I) = 0.
LOC = MLOC
ENDIF
ENDIF
150 IF ( II .GT. 0 ) THEN
WRITE ( IU6, 5060 ) ITABNO, TITLE
IP = 1
ENDIF
ICC = 0
LZ = LOC
DO 180 ICL = 1,4
180 IDD(ICL) = 4H
190 IDL = ID
READ (IU12, 5070, END=200, ERR=6666 ) ID, N, (A(I), I = 1,N)
200 IF ( ID .EQ. 4HEOT ) GO TO 20
ICC = ICC + 1
IF ( ICC .LE. 4 ) IDD(ICC) = ID
IF ( ID .EQ. IDL ) GO TO 280
IF ( ID .NE. IDD(4) ) GO TO 210
IF ( IDL .EQ. IDD(2) ) GO TO 280
LOC = LE
L = LX
GO TO 220
210 CDNOZ(LOC) = N
L = LOC
IF ( ID .EQ. IDD(3) ) LX = L
IF ( ID .NE. IDD(2) ) GO TO 260
LY = L
LZ = LZ + 1
GO TO 260
C ... WRITE THE TABULAR DATA.
220 IF ( IP .NE. 0 ) THEN
LY = LY+1
WRITE(IU6,5080) IDD(1), CDNOZ(LZ), IDD(2), CDNOZ(LY)
JF = 0
M = N
LF = LX
240 NP = M
IF ( M .GT. 8 ) NP = 8
M = M - NP
LE = LF + NP
LF = LF + 1
WRITE(IU6,5090) IDD(3), (CDNOZ(I), I = LF,LE)
LF = LE
JE = JF + NP
JF = JF + 1
WRITE(IU6,5090) IDD(4), (A(I), I = JF,JE)
JF = JE
IF( M .GT. 0 ) GO TO 240
ENDIF
260 DO 270 I = 1,N
LOC = LOC + 1
CDNOZ(LOC) = A(I)
270 CONTINUE
LE = LOC
IF ( ID .EQ. IDD(4) ) CDNOZ(LOC+2) = 1.
LOC = L + 2*N + 6
IF ( LOC .GT. NMAX ) GO TO 300
GO TO 190
280 CDNOZ(LOC) = CDNOZ(LX)
L = LOC
DO 290 I = 1,N
LOC = LOC + 1
CDNOZ(LOC) = CDNOZ(LX+I)
290 CONTINUE
GO TO 220
300 WRITE(IU6,5100) ITABNO
ITABNO = 0
GO TO 30
400 CONTINUE
ITABNO = 0
GO TO 30
6666 CONTINUE
WRITE(IU6,6669) IU12
STOP
5000 FORMAT (I1,I4,A)
5010 FORMAT (//,33X,'TABLE DATA INPUT SUMMARY, ',I3,' TABLES',//,
1 28X,'TABLE NUMBER REFERENCE NUMBER ARRAY LOCATION')
5020 FORMAT (33X,I2,12X,I5,14X,I5)
5030 FORMAT (/,36X,'DATA STORAGE ALLOCATION ',I7,/,
1 36X,'DATA STORAGE NOT USED ',I7,/)
5040 FORMAT(10X,'THE FOLLOWING TABLES HAVE BEEN REPLACED',10(I5,','))
5060 FORMAT (//,3X,I4,A,/)
5070 FORMAT(A4,I3,3X,(T11,7F10.0))
5080 FORMAT(1X,A4,' = ',E13.5,1X,A4,' = ',E13.5)
5090 FORMAT(20X,A4,1X,8E13.5)
5100 FORMAT (' ********* TABLE OVER FLOW, TABLE ',I5,' NOT LOADED')
6669 FORMAT(/,' ERROR READING ENGINE TABULAR INPUT DATA FROM UNIT',
* I3,'.',/,' PROGRAM ABORTED IN SUBROUTINE TABRD.')
9992 CONTINUE
WRITE(IU6,9999) 'ERROR OPENING THE INPUT FILE ', CDFILE,
* ' AS UNIT ', IUNIT, '.',
* 'PROGRAM ABORTED IN SUBROUTINE CDRD.'
9999 FORMAT(//,1X,2A,/,A,I2,A,/,1X,A,/)
STOP
END
推荐答案
您收到一个错误,因为您的代码使用了编译器(Gfortran)不支持的非标准FORTRAN 77代码。
正如gfortran检测到的,您使用的是Hollerith常量4HEOT
。
Hollerith是字符类型的前身。最后一个允许使用Holleriths的Fortran标准是FORTRAN 66(ANSI X3.9-1966)。尽管它不是FORTRAN 77标准的一部分,但它包含了一个附录C,其中包含对希望将其作为扩展提供的处理器的建议。您对Hollerith的使用甚至没有遵循这些建议,特别是:
C3。对Hollerith常量的限制
Hollerith常量只能出现在DATA语句和CALL语句的参数列表中。
那么这是怎么回事?
代码的相关语句为
IMPLICIT INTEGER*4 (I-N)
READ (IU12, 5070, END=200, ERR=6666 ) ID, N, (A(I), I = 1,N)
200 IF ( ID .EQ. 4HEOT ) GO TO 20
5070 FORMAT(A4,I3,3X,(T11,7F10.0))
变量
ID
使用符合非标准的integer*4
语法隐式声明为4字节整数(有关详细信息,请参阅Fortran: integer*4 vs integer(4) vs integer(kind=4))。READ
语句使用A4
编辑描述符为ID
赋值。这是FORTRAN 77标准的附录C允许读取Hollerith变量的方式:c1。Hollerith数据类型
Hollerith是一种数据类型;但是,符号名称不能是Hollerith类型。 Hollerith数据,而不是常量,以类型名称的名义进行标识 整数、实数或逻辑。它们不能打着文字的幌子来辨认。[...]Hollerith基准是一个字符串。[.]空白字符在霍尔瑞斯基准中很重要。Hollerith数据的内部表示形式可能与其他数据类型不同。
可以通过DATA语句(C4)或READ语句(C6)用Hollerith值定义整型、实型或逻辑型实体。[.]当使用Hollerith值定义整数、实数或逻辑类型的实体时,该实体及其关联将变为未定义,不能用作整数、实数或逻辑基准。C6。A编辑Hollerith数据
当输入/输出列表项的类型为整型、实型或逻辑型时,Aw编辑描述符可与Hollerith数据一起使用。在输入时,输入列表项将使用Hollerith数据定义。在输出时,列表项必须使用Hollerith数据定义。编辑与字符数据的Aw编辑相同,但len是单个数字存储单元中可以存储的最大字符数。
ID
包含描述4个字符的Hollerith数据。每个字节有一个字符,并且ID
定义为4字节变量,这看起来很好。IF
语句将Hollerith变量ID
与Hollerith常量4HEOT
进行比较(根据上下文,可能是为了检查您是否在表的末尾)。即使是建议的标准扩展似乎也不支持这一点,但是,嘿,最后我们有两个由4个字符组成的字符串,所以判断它们是否相等应该不是很困难。遗憾的是,gfortran从未被告知如何做到这一点(讽刺模式关闭)。
如何修复此问题?
我可以想到许多可能性(除了找到编写此代码的人,他可能已经退休,并友好地请求他修复它)。面向未来的最佳解决方案是选项1:
选项1
通过引入新的字符变量来重写代码,以便所有带有字符编辑描述符(A[w])的I/O都对应于列出的字符变量。将有问题的Hollerith常量替换为字符常量"EOT "
。
选项2
一些Fortran编译器喜欢使用字符编辑描述符读写整数,而不是特别擅长记住这些整数是Hollerith变量而不是实际的整数。使用这些编译器之一(例如,gfortran):如您所见,它认为ID
仍然是一个整数,而不是Hollerith。因此,假设ID
保持为一个整数,并且读取操作只是将4个字符的变量读入其中。
在这种情况下,您可以将Hollerith常量替换为它要编码的整数。您可以这样做,例如,通过定义
DATA ID_EOT/4HEOT /
现在ID_EOT
具有整数值(可能是ICHAR("E")+256*(ICHAR("O")+256*(ICHAR("T")+256*ICHAR(" ")))
),您可以将有问题的IF
语句替换为
200 IF ( ID .EQ. ID_EOT ) GO TO 20
此选项不符合标准,因此不可移植,并且可能会在将来(对您或其他人)造成与您现在遇到的问题类似的问题。然而,它至少会符合关于如何实现扩展的书面建议,这比您现在拥有的要好。
以下编译器(检查的版本)似乎支持带有Hollerith的数据语句:Intel(17.0.4)、gfortran(7.3.0)、Cray(8.5.8)、PGI(18.4)、NAG(6.2)和Sun(8.8)。除了NAG编译器之外,所有这些编译器似乎都允许读/写带有字符编辑描述符的整数。请注意,测试非常有限,仅限于4HEOT
常量。
选项3
使用能够处理您的代码的编译器-我相信英特尔Fortran可以编译并运行它。
此选项不符合标准,因此不可移植,并且可能会在将来(对您或其他人)造成与您现在遇到的问题类似的问题。它甚至不符合FORTRAN 77标准附录C中的扩展建议。这是一种需要更少工作的选择,代价是不改进任何东西,并为未来保持问题的完整性--那时使用FORTRAN 66编码的人将会更少。
这篇关于错误:逻辑运算符(1)的操作数为整数(4)/Hollerith的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!