为什么第二个if子句甚至执行? [英] Why does the second if-clause even execute?

查看:119
本文介绍了为什么第二个if子句甚至执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的程序中有一个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

其中,iinri是标量整数,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆