Fortran DO循环,警告仅使用整数

Myc*_*ofD 6 fortran gfortran fortran90 fortran95

我在我的Ubuntu 15.04系统上安装了gfortran.在编译Fortran代码时,DO循环仅要求获取整数参数,而不是实数值或变量.这包括循环变量和步骤表达式.为什么它也不能采取真正的价值观呢?

以下是从这里开始的程序,练习3.5的嵌套do循环部分.

        program  xytab
        implicit none
        !constructs a table of z=x/y for values of x from 1 to 2 and 
        !y from 1 to 4 in  steps of .5
        real         ::   x, y, z 
        print *, '           x           y           z'
        do  x = 1,2
            do y = 1,4,0.5
                z = x/y
                print *, x,y,z
            end do
        end  do
        end  program xytab
Run Code Online (Sandbox Code Playgroud)

编译后显示的错误是:

xytab.f95:8.4:

 do y = 1,4,0.5
    1
Warning: Deleted feature: Loop variable at (1) must be integer
xytab.f95:8.12:

 do y = 1,4,0.5
            1
Warning: Deleted feature: Step expression in DO loop at (1) must be integer
xytab.f95:7.3:

do x = 1,2
   1
Warning: Deleted feature: Loop variable at (1) must be integer
Run Code Online (Sandbox Code Playgroud)

fra*_*lus 13

Fortran标准现在要求do构造的循环控制由(标量)整数表达式给出,并且循环变量是(标量)整数变量.循环控件由start,step和stop表达式组成(步骤表达式为0.5).请参见Fortran 2008文档的R818和R819(8.1.6.2).那么,这是一个简短而简单的答案:标准是这样说的.

它有点复杂,因为来自编译器的消息表明了这一点.在Fortran中使用其他形式进行循环控制直到Fortran 95.也就是说,从Fortran 95开始使用真实表达式是一个已删除的功能.

使用真实表达有什么害处?如果使用得当,人们可以想象,没有任何伤害.但是与它们的便携性存在真正的困难.

考虑

do x=0., 1., 0.1
 ...
end do
Run Code Online (Sandbox Code Playgroud)

多少次迭代?那将是(根据Fortran 90的规则)MAX(INT((m2 – m1 + m3) / m3), 0),其中(m1是起始值(0.),m2停止值(1.)和m3步长值(0.1)).是10或11(甚至9)?它完全取决于您的数字表示:我们记得,它0.1可能不能完全表示为实数,并INT在转换为整数时截断.您还必须担心重复添加实数.

因此,使用整数并在循环内部进行一些算术运算

do y_loop = 0, 6
  y = 1 + y_loop/2.
  ...
end do
Run Code Online (Sandbox Code Playgroud)

要么

y = 1
do
  if (y>4) exit
  ...
  y = y+0.5
end do
Run Code Online (Sandbox Code Playgroud)

最后,你提到.f90.f95提交后缀.gfortran并不首先表示源代码遵循Fortran 90标准(代码可以正常).此外,来自编译器的消息仅仅是警告,可以使用该-std=legacy选项来抑制这些消息.相反,使用-std=f95(或后来的标准)这些都会成为错误.


作为奖励有趣的事实,请考虑下面的Fortran 90代码.

real y
integer i

loop_real: do y=1, 4, 0.5
end do loop_real

loop_integer: do i=1, 4, 0.5
end do loop_integer
Run Code Online (Sandbox Code Playgroud)

虽然命名的循环loop_real有效,但名称loop_integer不是.在计算迭代计数时,三个表达式将转换为循环变量的类型参数. INT(0.5)0.

  • 在许多实现中,0.1并不是完全可表示的.如果精确值为0.9999或1.00001,则会得到彼此不同的迭代计数,以及精确值确实为0.1的迭代计数.注意,`INT`是用截断定义的,而不是最近的舍入. (2认同)