6

I am getting different behavior between Portland and Intel fortran compilers when evaluating a simple expression with an exponent followed by a multiply. I am pretty sure that pgf90 (and gfortran) are working correctly based on my understanding of operator precedence, but I would like a second opinion since these things can get a bit tricky.

Here is my code simplified down to a very basic form. When run with ifort the expression of the form d1=a**-2*b gets interpretted as d1=a**(-2*b) by ifort by as d1=(a**-2)*b by pgf90 and gfortran. If I remove the negative sign from the exponent, all three compilers interpret this as d1=(a**2)*b. If I change *b to +b I also get good behavior from all three.

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

Is there a history behind these differences so that they should be considered a "feature"? Or, is this an outright bug on Intel's part?

4

1 回答 1

6

在网上搜索,我发现不允许两个连续运算符的说法。因此,解释而不是拒绝这个表达是对语言的扩展。该扩展已由不同的编译器供应商以不同的方式实现。

实际上,当我将 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)它更多的是一个扩展而不是一个错误,3)即使这个表达式是语言允许的,gfortran 的建议是好的——使用括号即使不需要也清晰。

于 2013-03-14T18:20:08.630 回答