Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fortran DO loop, warning to use integer only

I installed gfortran on my Ubuntu 15.04 system. While compiling Fortran code, the DO loop asks to take integer parameters only and not real values or variables. That includes the loop variable and the step expression. Why can't it take real values too?

The following is a program taken from here, exercise 3.5 of the section nested do loops.

        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

The error shown after compiling is:

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
like image 526
MycrofD Avatar asked Jun 08 '15 11:06

MycrofD


People also ask

What is implied DO loop in Fortran?

Implied DO loops Basically, these loops are a shorthand that was introduced in FORTRAN to provide a method for array initialization and to cut back on the number of lines of code that where required in the program.

How do you break a loop in Fortran?

Exit statement terminates the loop or select case statement, and transfers execution to the statement immediately following the loop or select.

Do loops Fortran 77?

Fortran 77 has only one loop construct, called the do-loop. The do-loop corresponds to what is known as a for-loop in other languages. Other loop constructs have to be built using the if and goto statements.


1 Answers

The Fortran standard now requires that a do construct's loop control is given by (scalar) integer expressions and that the loop variable is a (scalar) integer variable. The loop control consists of the start, step, and stop expressions (your step expression is 0.5). See R818 and R819 (8.1.6.2) of the Fortran 2008 document. That, then, is the short and simple answer: the standard says so.

It's a little more complicated than that, as the messages from the compiler suggest. Using other forms for loop control was present in Fortran up until Fortran 95. That is, from Fortran 95 onward using real expressions is a deleted feature.

What harm is there in using real expressions? Used correctly, one could imagine, there is no harm. But there's real difficulty in portability with them.

Consider

do x=0., 1., 0.1
 ...
end do

How many iterations? That would be (under the rules of Fortran 90) MAX(INT((m2 – m1 + m3) / m3), 0) where (m1 is the start value (0.), m2 the stop value (1.) and m3 the step value (0.1)). Is that 10 or 11 (or even 9)? It depends entirely on your numeric representation: we recall that 0.1 may not be exactly representable as a real number and INT truncates in converting to integer. You'd also have to worry about repeated addition of real numbers.

So, use integers and do some arithmetic inside the loop

do y_loop = 0, 6
  y = 1 + y_loop/2.
  ...
end do

or

y = 1
do
  if (y>4) exit
  ...
  y = y+0.5
end do

Finally, you mention .f90 and .f95 file suffixes. gfortran doesn't take the first to mean that the source code follows the Fortran 90 standard (where the code would be fine). Further, the messages from the compiler are merely warnings, and these can be suppressed using the -std=legacy option. Conversely, using -std=f95 (or later standards) these become errors.


As a bonus fun fact consider the following piece of Fortran 90 code.

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

While the loop named loop_real is valid, that named loop_integer isn't. In the calculation of the iteration count the three expressions are converted to the kind, with kind parameters, of the loop variable. INT(0.5) is 0.

like image 67
francescalus Avatar answered Oct 19 '22 09:10

francescalus