为什么第二个if子句甚至执行? [英] Why does the second if-clause even execute?
问题描述
我的程序中有一个do while
循环,谁有继续的条件,这总是给我一个错误,我不知道为什么.看起来像这样:
I have a do while
loop in my program, who's condition to continue keeps giving me off-by-one errors and I can't figure out why. It looks like this:
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.
-但程序崩溃了.
where ii
and nri
are scalar integers, e1
is a scalar real, and ed
is a real array of length nri
. What I expect to happen after the last run is that since ii.le.nri
returns .false.
the second condition is never tested, and I don't get any off-by-one problems. I've verified with the debugger that ii.le.nri
really does return .false.
- and yet the program crashes.
为验证我的假设,即仅测试一个条件,我什至编写了一个小的测试程序,并使用相同的编译器选项进行了编译:
To verify my assumption that only one condition is tested, I even wrote a small test program, which I compiled with the same compiler options:
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
按照我的预期,运行该程序只会输出
Running this program outputs, as I expected, only
$ ./iftest
in returns false
并退出.第二项测试永远不会运行.
and exits. The second test is never run.
为什么这不适用于我的do while
子句?
Why doesn't this apply to my do while
clause?
推荐答案
与某些语言相比,Fortran不保证复合逻辑表达式的任何特定求值顺序.就您的代码而言,最后一次回合while循环,将ii
的值设置为nri+1
.对于您的编译器来说,生成测试ed(nri+1)<=e1
的代码并由此引用ed
范围之外的元素是合法的.这很可能是程序崩溃的原因.
In contrast to some languages Fortran does not guarantee any particular order of evaluation of compound logical expressions. In the case of your code, at the last go round the while loop the value of ii
is set to nri+1
. It is legitimate for your compiler to have generated code which tests ed(nri+1)<=e1
and thereby refer to an element outside the bounds of ed
. This may well be the cause of your program's crash.
您的期望与该语言的Fortran标准规定相反.
Your expectations are contrary to the Fortran standards prescriptions for the language.
如果还没有这样做,请尝试在打开数组边界检查的情况下重新编译代码,然后看看会发生什么情况.
If you haven't already done so, try recompiling your code with array-bounds checking switched on and see what happens.
关于您的测试为什么没有解决这个问题的原因,我怀疑您的所有测试确实表明,您的编译器针对不同的条件种类生成了不同的执行顺序,并且您并未真正进行比较一样.
As to why your test didn't smoke out this issue, well I suspect that all your test really shows is that your compiler generates a different order of execution for different species of condition and that you are not really comparing like-for-like.
这篇关于为什么第二个if子句甚至执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!