我是Fortran的新手。所以我需要帮助。我在SUSE上使用gfortran编译代码并收到以下错误:
git push
代码主文件附在下面的链接中,其中1818行显示错误。
我文件的链接是:https://files.engineering.com/getfile.aspx?folder=cd6961f3-d38b-4e61-a43d-269fa18c7d11&file=sfeng.f
该如何解决?
为简化/最小的示例,我在此处添加了代码:
200 IF ( ID .EQ. 4HEOT ) GO TO 20
1
Error: Operands of logical operator '.eq.' at (1) are INTEGER(4)/HOLLERITH
答案 0 :(得分:3)
由于代码使用了编译器(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
语句使用ID
编辑描述符为A4
分配一个值。这是FORTRAN 77标准的附录C允许读取Hollerith变量的方式:
C1。 Hollerith数据类型
Hollerith是一种数据类型;但是,符号名称不能为Hollerith类型。 Hollerith数据(不是常量)是根据类型名称来标识的 整数,实数或逻辑。切勿以字符为幌子来标识它们。 [...]
Hollerith基准是一个字符串。 [...]空白字符在Hollerith基准中很重要。 Hollerith数据的内部表示形式可能与其他数据类型不同。
可以通过DATA语句(C4)或READ语句(C6)用Hollerith值定义整数,实数或逻辑类型的实体。 [...]当使用Hollerith值定义整数,实数或逻辑类型的实体时,该实体及其关联将变为未定义,以用作整数,实数或逻辑基准。
C6。 Hollerith数据的编辑
当输入/输出列表项的类型为整数,实数或逻辑类型时,Aw编辑描述符可与Hollerith数据一起使用。输入后,输入列表项将使用Hollerith数据进行定义。输出时,必须使用Hollerith数据定义列表项。
编辑与字符数据的Aw编辑相同,只是len是单个数字存储单元中可以存储的最大字符数。
因此,现在整数变量ID
包含描述4个字符的Hollerith数据。每个字节一个字符,并且ID
定义为4个字节的变量,这看起来不错。
IF
语句将Hollerith变量ID
与Hollerith常数4HEOT
(在给定上下文的情况下,可能检查您是否在表尾)进行比较。甚至建议的标准扩展似乎都无法支持这一点,但是,最后,我们有两个由4个字符组成的字符串,因此确定它们是否相等应该不是很困难。从来没有告诉过gfortran如何做到这一点(可怜的离子模式关闭),这只是一个可怜的事情。
我可以想到很多可能性(除了找到编写此代码的人之外,他很可能已经退休,并且很高兴要求他进行修复)。未来最好的解决方案是方案1:
通过引入新的字符变量来重写代码,以便所有带有字符编辑描述符(A [ w ])的I / O均与列出的字符变量相对应。将有问题的Hollerith常量替换为字符常量"EOT "
。
一些Fortran编译器乐于使用字符编辑描述符来读取和写入整数,并且并不特别擅长记住那些整数是Hollerith变量而不是实际整数。使用其中一种编译器(例如gfortran):如您所见,它认为ID
仍然是整数,而不是Hollerith。因此,假设ID
保留为整数,并且read操作只是将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的DATA语句:Intel(17.0.4),gfortran(7.3.0),CRAY(8.5.8),PGI(18.4),NAG(6.2)和Sun(8.8)。除了NAG编译器外,它们似乎都允许使用字符编辑描述符读取/写入整数。请注意,测试非常有限,仅限于4HEOT
常量。
使用可以处理您代码的编译器-我相信Intel Fortran可以编译并运行它。
此选项不符合标准,因此不可移植,并且将来可能会(对您或其他人)造成与您现在遇到的问题类似的问题。它甚至不符合FORTRAN 77标准附录C中的扩展建议。该选项所需的工作量更少,但代价是不进行任何改进,并在将来保持问题完整无缺-那时用FORTRAN 66编写代码的人将会减少。
答案 1 :(得分:0)
正如编译器错误所述,您正在将HOLLERITH
与string
进行比较,我刚刚发现是{em> FORTRAN77之前使用的integer
字符!
您无法将string
与string
进行比较。
如果要使用integer
转换read
中的write
,请参见here。
如果要比较字符串,请改用CROSS JOIN
。
答案 2 :(得分:0)
有两种解决方法。当然可以将所有Hollerith
常量更改为CHARACTER
变量,但是考虑到Hollerith
子程序的参数不会像{ {1}}个参数可以。在支持这种语法的编译器中,CHARACTER
常量在表达式中的行为通常不一致,文档记载不清,并且几乎不受支持。在Hollerith
语句中可能会得到更好的支持,但是不要指望它。
gfortran表示它们支持DATA
常量作为函数参数,但是最早支持Hollerith
文字的经典转换函数(如INT
)不起作用:请参见下面的示例。如果您喜欢遥远的狂笑声,可以向bugzilla发送有关此问题的错误报告。我在BOZ
和一项作业中获得了更大的成功:
TRANSFER