带ifort的指数的Fortran运算符优先级错误
我发现波特兰编译器和英特尔fortran编译器在计算一个简单表达式时表现出了不同的行为,该表达式后面是一个指数,后面是一个乘法。根据我对运算符优先级的理解,我非常确定pgf90(和gfortran)工作正常,但我想听听第二种意见,因为这些事情可能会变得有点棘手 这里是我的代码简化为一个非常基本的形式。当使用ifort运行时,带ifort的指数的Fortran运算符优先级错误,fortran,operator-precedence,intel-fortran,Fortran,Operator Precedence,Intel Fortran,我发现波特兰编译器和英特尔fortran编译器在计算一个简单表达式时表现出了不同的行为,该表达式后面是一个指数,后面是一个乘法。根据我对运算符优先级的理解,我非常确定pgf90(和gfortran)工作正常,但我想听听第二种意见,因为这些事情可能会变得有点棘手 这里是我的代码简化为一个非常基本的形式。当使用ifort运行时,d1=a**-2*b形式的表达式被解释为d1=a**(-2*b)由ifort通过asd1=(a**-2)*b通过pgf90和gfortran。如果我从指数中删除负号,所有三个
d1=a**-2*b
形式的表达式被解释为d1=a**(-2*b)
由ifort通过asd1=(a**-2)*b
通过pgf90和gfortran。如果我从指数中删除负号,所有三个编译器都会将其解释为d1=(a**2)*b
。如果我把*b改为+b,我也会从这三个方面得到良好的表现
program badvals
implicit none
real :: a, b, c1, c2, d1, d2
a = 2.
b = 4.
! Works with addition following the exponent.
c1 = a**-2+b
c2 = a**(-2)+b
! Ifort differs with multiplication following negative exponent.
d1 = a**-2*b
d2 = a**(-2)*b
print*, "c1, d1 = ",c1, d1
print*, "c2, d2 = ",c1, d2
print*, "c2-c1, d2-d1 = ",c2-c1, d2-d1
end program badvals
!Program output for ifort v13.0.1.117: (either -O0 or -fast):
! c1, d1 = 4.250000 3.9062500E-03
! c2, d2 = 4.250000 1.000000
! c2-c1, d2-d1 = 0.0000000E+00 0.9960938
!Program output for pgf90 v12.10-0: (either -O0 or -fast):
! c1, d1 = 4.250000 1.000000
! c2, d2 = 4.250000 1.000000
! c2-c1, d2-d1 = 0.000000 0.000000
!Program output for gfortran v4.1.2: (either -O0 or -O3):
! c1, d1 = 4.250000 1.000000
! c2, d2 = 4.250000 1.000000
! c2-c1, d2-d1 = 0.000000 0.000000
这些差异背后是否有历史渊源,因此应将其视为“特征”?或者,这是英特尔方面的一个彻头彻尾的错误吗?在搜索web时,我发现不允许两个连续的运算符。因此,解释而不是拒绝这个表达是语言的延伸。不同的编译器供应商实现了不同的扩展 事实上,当我将gfortran与限制性编译器选项一起使用时,它拒绝了以下代码示例:
badvals.f90:9.11:
c1 = a**-2+b
1
Error: Extension: Unary operator following arithmetic operator (use parentheses) at (1)
badvals.f90:13.11:
d1 = a**-2*b
1
Error: Extension: Unary operator following arithmetic operator (use parentheses) at (1)
类似地,带有限制性编译器选项的ifort提供以下功能:
badvals.f90(9): warning #7026: Non-standard extension
c1 = a**-2+b
----------^
badvals.f90(13): warning #7026: Non-standard extension
d1 = a**-2*b
----------^
因此:
1) 使用编译器的警告和错误选项非常有用,
2) 与其说是bug,不如说是扩展,
3) 即使该语言允许使用此表达式,gfortran的建议也很好——即使不需要,也要使用括号以保持清晰。“不允许使用两个连续运算符”需要一些限定条件-它适用于此处,因为第二级表达式(算术表达式)的语法规则,但通常不适用于<代码>待办事项或。不to_be是可以的(在莎士比亚的Fortran语言中很常见),你也可以在其中插入一个定义的一元运算符。如果OP需要扩展的正式描述,他们可以读取。这些限制性选项是什么?因此,根据MSB和IanH的响应,这将是ifort的一个“功能”。一般来说,我从中得到的是,我需要在我的思维中加入“不要将两个算术运算符放在一起”的规则。和往常一样,要慷慨地使用括号。IanH提供的链接对于理解ifort的想法非常有帮助。将*更改为a+时,我看到的不同行为是因为一元+-优先级介于*和二进制+-之间。