Fortran 逻辑操作顺序(潜在ifort错误)

Fortran 逻辑操作顺序(潜在ifort错误),fortran,intel-fortran,Fortran,Intel Fortran,在英特尔论坛上将此报告为编译器错误之前,我想知道以下内容是否符合标准。我的问题是:在Fortran中,逻辑运算的顺序总是固定的吗 ! main.f90 interface subroutine f(x) logical, intent(in), optional :: x end subroutine f end interface call f(.false.) call f(.true.) call f() end program !

在英特尔论坛上将此报告为编译器错误之前,我想知道以下内容是否符合标准。我的问题是:在Fortran中,逻辑运算的顺序总是固定的吗

! main.f90
  interface
     subroutine f(x)
       logical, intent(in), optional :: x
     end subroutine f
  end interface
  call f(.false.)
  call f(.true.)
  call f()
end program

! f.f90
subroutine f(x)
  logical, intent(in), optional :: x
  print*, present(x) .and. x
end subroutine f
gfortran main.f90 f.f90&&a.out
打印

F
T
F
 F
 T
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
a.out              0000000000476D75  Unknown               Unknown  Unknown
a.out              0000000000474997  Unknown               Unknown  Unknown
a.out              0000000000444264  Unknown               Unknown  Unknown
a.out              0000000000444076  Unknown               Unknown  Unknown
a.out              0000000000425176  Unknown               Unknown  Unknown
a.out              00000000004027A0  Unknown               Unknown  Unknown
libpthread.so.0    00007F3560702E80  Unknown               Unknown  Unknown
a.out              0000000000402633  Unknown               Unknown  Unknown
a.out              000000000040260F  Unknown               Unknown  Unknown
a.out              00000000004025AE  Unknown               Unknown  Unknown
libc.so.6          00007F3560371710  Unknown               Unknown  Unknown
a.out              00000000004024A9  Unknown               Unknown  Unknown
ifort main.f90 f.f90&&/a.out
打印

F
T
F
 F
 T
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
a.out              0000000000476D75  Unknown               Unknown  Unknown
a.out              0000000000474997  Unknown               Unknown  Unknown
a.out              0000000000444264  Unknown               Unknown  Unknown
a.out              0000000000444076  Unknown               Unknown  Unknown
a.out              0000000000425176  Unknown               Unknown  Unknown
a.out              00000000004027A0  Unknown               Unknown  Unknown
libpthread.so.0    00007F3560702E80  Unknown               Unknown  Unknown
a.out              0000000000402633  Unknown               Unknown  Unknown
a.out              000000000040260F  Unknown               Unknown  Unknown
a.out              00000000004025AE  Unknown               Unknown  Unknown
libc.so.6          00007F3560371710  Unknown               Unknown  Unknown
a.out              00000000004024A9  Unknown               Unknown  Unknown

我使用的是GCC 5.3.0和Ifort 16.0.2。

不,Fortran标准不能保证逻辑表达式求值的顺序。就像数学表达式一样,编译器可以自由地将它们重新排序,使之在“真实逻辑”(或“真实数学”)的完美世界中是等价的,但在不完美的计算机世界中是不等价的

您可以强制执行以下评估顺序:

if (.not. present(x)) then
    print*, .false. 
else
    print*, x
end if
我的标准草案副本包括该条款

7.1.5.4.2逻辑内在操作的评估

一旦建立了逻辑内在操作的解释,则 处理器可以计算逻辑上正确的任何其他表达式 等效,前提是任何 表达式不受侵犯


我对标准的解释是程序不符合,因为它引用了一个不存在的可选参数。参考第12.5.2.12.3(1)节,该节对此作出了规定。因为
.and.
运算符的操作数求值顺序未定义
x
在不存在时可能会被引用。

我实际上习惯于编写类似于
if(present(x).and.x).
的内容,这似乎总是有效的。我想我应该改变这个习惯。@RaulLaasner你确实应该改变这个习惯,它在C和类似语言中工作,而不是在Fortran中。有趣的是,只有当
f
在一个单独的文件中时,它才会失败(使用ifort)。如果它在同一个源文件中,或者在
contains
部分中,它运行良好。此外,我是否编写
present(x)也没有区别。x
x。和。present(x)
-
x
似乎总是先求值,所以这确实取决于编译器。@francescalus我现在明白你的意思了。在这种情况下,它确实不符合标准。