我的程序中有一个do while
循环,有条件继续不断地给我一个错误,我无法弄清楚原因。它看起来像这样:
do while (ii .le. nri .and. ed(ii) .le. e1)
! do some stuff...
ii = ii + 1
end do
其中ii
和nri
是标量整数,e1
是标量实数,ed
是一个长度为nri
的真实数组。我希望在最后一次运行后发生的事情是,因为ii.le.nri
返回.false.
,所以第二个条件从未经过测试,而且我没有得到任何一个一个一个的问题。我已经通过调试器验证ii.le.nri
确实 返回.false.
- 但程序崩溃了。
为了验证我的假设只测试了一个条件,我甚至编写了一个小的测试程序,我使用相同的编译器选项编译:
program iftest
implicit none
if (returns_false() .and. returns_true()) then
print *, "in if block"
end if
contains
function returns_true()
implicit none
logical returns_true
print *, "in returns true"
returns_true = .true.
end function
function returns_false()
implicit none
logical returns_false
print *, "in returns false"
returns_false = .false
end function
end program
正如我所料,运行此程序输出仅
$ ./iftest
in returns false
并退出。第二次测试永远不会运行。
为什么这不适用于我的do while
条款?
答案 0 :(得分:7)
与某些语言相比,Fortran不保证复合逻辑表达式的任何特定评估顺序。对于您的代码,最后围绕while循环,ii
的值设置为nri+1
。编译器生成测试ed(nri+1)<=e1
的代码从而引用ed
范围之外的元素是合法的。这可能是程序崩溃的原因。
您的期望与该语言的Fortran标准处方相反。
如果您还没有这样做,请尝试重新编译代码,并打开数组边界检查,看看会发生什么。
至于为什么你的测试没有冒出这个问题,我怀疑你的所有测试都表明你的编译器为不同的条件种类生成了不同的执行顺序,并且你并没有真正比较像样。
答案 1 :(得分:4)
扩展答案High Performance Mark,这是重写循环的一种方法:
ii_loop: do
if (ii .gt. nri) exit ii_loop
if (ed(ii) .gt. e1) exit ii_loop
! do some stuff
ii = ii + 1
end do ii_loop