Do loop do i=m+1,n executes even when m+1>n

Do loop do i=m+1,n executes even when m+1>n

I am an experienced Fortran developer for 20+ years developing chemical engineering software for the energy industry. I have been using Intel Fotran (v 10.1.024) since 2008 as it was adopted by the AspenTech chemical engineering software as part of its simulator. However, my legacy programs that had been compiled successfully with several compilers including CVF (6.6C), experience many unexplained errors in Intel Fortran. My questions to the forum are:

1. Is there a list of settings available where Intel Fortran is completely compatible with legacy CVF code? One such setting is the option /iface:cvf and that eliminates many of the error messages but not all.

2. There are a number of cases where there are run-time errors that should not occur. For example, I have the following piece of code (written in simplified format to illustrate the point):

integer(4) :: i, m, n
real(8) :: t, x(3)
m = 3
n = 3
t = 0.0
do i = m+1,n
if (x(i) > 0.0) then
t = t + 1.0
end if
end do

In the above code, the do loop should not execute since m+1 is greater than n (4>3). However, Intel fortran executes the body of the loop resulting in an error since an attempt is made to access the fourth element of x. The locals window confirms that i=4 when the break point was encountered within the loop while executing the if statement. Again, other do-loops with a similar structure work fine.

3. Will it help to have a newer version of the compiler?

This is baffling and frustrating. Please help. I have avoided these problems by sticking to my legacy version of Compaq Fortran for several years but the new Windows 7 computer and AspenPlus are no longer compatible with CVF.

Best,

Avinash

Dr. Avinash R. Sirdeshpande

Director, Process Design and Modeling,
GreatPoint Energy
Chicago

13 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Did you use the /Qonetrip option, by any chance? (That is a compiler option that is provided to allow legacy Fortran code to continue to malfunction in a satisfactory way). Otherwise, the loop should not be executed. It is not likely that any Fortran compiler would commit such a simple error.

Please provide a complete example, and state your OS details (in particular, do you run 32-bit or 64-bit EXEs).

(mecej beat me to it, but anyway...) What compile options are you using?  Simplifying your example:

  implicit none
  integer :: i, j
  j = 0
  do i = 4,3
    j = j + 1
  end do
  print "('j is ',i0)", j
END

>ifort /check:all /warn:all "2013-01-30 aspen.f90" && "2013-01-30 aspen.exe"
Intel(R) Visual Fortran Compiler XE for applications running on IA-32, Version 13.0.1.119 Build 20121008
Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.
"-out:2013-01-30 aspen.exe"
-subsystem:console
"2013-01-30 aspen.obj"
j is 0
>ifort /check:all /warn:all /f66 "2013-01-30 aspen.f90" && "2013-01-30 aspen.exe"
Intel(R) Visual Fortran Compiler XE for applications running on IA-32, Version 13.0.1.119 Build 20121008
Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.
"-out:2013-01-30 aspen.exe"
-subsystem:console
"2013-01-30 aspen.obj"
j is 1

It has been several years now since I've written Fortran code for Aspen Plus, but based on my recollections of their "level" of Fortran in use (Hollerith constants used for component names, etc) it wouldn't surprise me if /f66 was included in any build scripts provided with that product.  /f1066 wouldn't surprise me in some respects.

Bonus points question: If, in IanH's program, you print the value of the loop counter i after the Do loop has been executed or skipped, what is the value printed (i) with /Qonetrip and (ii) without that option? (Ian, I prefer "onetrip" to "f66" since the latter induces guilt feelings when I try it on source code that is not on punched cards).

Trying to explain the result in terms of the explanation of DO loops work in Fortran (as may be read in the Fortran standard or a book on Fortran 9x,2kx) may be instructive.

In Fortran 66 (see http://www.fh-jena.de/~kleine/history/languages/ansi-x3dot9-1966-Fortran... ), the parameters m1,m2,m3 in DO nn I=m1,m2,m3 were required to be positive, and the loop control variable I became undefined after a normal completion of the DO loop. I don't know if modern Fortran compilers try to enforce these old rules when options such as /f66 are used.

A control loop variable may become undefined when following the FORTRAN 66 rules, but as there is no way for an actual integer variable to have a value that indicates "undefined" (real variables may attain "Not-a-number" which could be used for that), a compiler would really have to reset it to some arbitrary value. I think it is more a matter of "thou should not use the control variable after a DO-loop before assigning it a well-defined value"

Regards,

Arjen

In my experience, in both F77 and F90+, after completion of a DO loop the index had a value equal to what it would be on the next iteration (had it not been stopped by the max value). For example, in the loop DO i = 1, 10, after completing ten cycles, i would have the value 11.

On rare occasions I have even relied on this behavior to use i in subsequent calculations. Maybe that's stupid, but it always worked. If it is really bad practice, I invite enlightenment.

The standard says "When a DO construct becomes inactive, the DO variable, if any, of the DO construct retains its last defined value." It is safe to use this - assuming the value becomes defined. Even if the iteration count ends up being zero, the DO variable is defined as the initial value.

Steve - Intel Developer Support

Thanks to everyone for providing this valuable feedback.

The problem with my code is that the do block executes when it should not. I have attached a .jpeg file with a screen shot of the IVF interface and the error produced. Also attached is the error message in the DOS window. The green arrow on the left indicates the break point that was triggered. The locals window shows the values of the relevant variables.

Sidebar - for those interested, the program calculates the temperature at which a liquid mixture will begin to boil at a given pressure.

Here CL%ncfc has a value of 3 and CL%nc also has a value of 3 as can be seen in the locals window. Hence, the loop index i is supposed to go from 4 to 3. According to the Fortran standard and that of IVF, the body of the loop must not execute. However, in practice the body of the loop does execute and since the user-defined member array CL%C(:) has been dimensioned to be of size CL%nc, an attempt is made to access the element 4 of an array of size 3. So the debugger is correct to catch it. We can also see that i has a value of 4, as it should. You will note that I have commented out an if-block that wraps this do-loop. To get the program to function, I have to invoke the help of this if-block to get the code to run.

I understand that IVF is a successor to CVF, which was a successor to DEC Fortran and Microsoft Visual Fortran. When compiled and run on my XP machine with CVF, this same program has no problems. Similarly, it is successfully run with gcc/gfortran. I use the text by Metcalf and Reid as my Fortran 90/95 standard. I am now wondering whether there is a bug in my compiler.

My responses to the 6 responses above are:

1. The only additional option I am using is /iface:cvf. I am using the 32-bit option.

2. The command line tab reads as follows:

/nologo /Zi /Od /gen-interfaces /warn:interfaces /iface:cvf /module:"Debug\\" /object:"Debug\\" /traceback /libs:static /threads /dbglibs /c

3. The simple example provided by IanH compiles and runs as expected i.e. j = 0 at the end of the program.

4. The new version of AspenPlus is completely compiled in Intel Fortran and they don't seem to have any problems with their legacy code. As was rightly pointed out, some of the code is in F66 and F77 since the Aspen program started in the 70's and FORTRAN since then has been the default standard for chemical engineering calculations. The program allows the user to enter Fortran code in F77 to provide intermediate data required for the run.

Attachments: 

My recollection is that for the example loop DO i = 1, 10; since Fortran 77 (without an internal exit or goto) i would have the value 11 on exit. Most pre F77 compilers (f66 ?) I used would exit with i=10. The change with F77 was that the execution test occurred at the start of the loop, while previously it was typically at the end.
The other main change with the F77 standard was for the case DO i = i1,i2, that the loop operation was based on the value of i1 and i2 at the initiation of the loop, while prior to F77, if the value of i2 was changed, the loop termination would change. This feature was used for testing the end of a growing list. ( I can't recall changing the value of i1 having any impact on the loop operation)

Since F77, the value of i on exit from the loop is now defined by the standard and not arbitarily defined by the compiler developer. Testing the value of i, to determine how the loop terminated, is not stupid, but a reliable technique provided by the standard definition.

John

Ps: you should try the coding example, with and without /f66 option to see how ifort deals with i and j

implicit none
  integer :: i, j
  j = 0
  do i = 4,3
    j = j + 1
  end do
  print "('j is ',i0)", j
  print "('i is ',i0)", i
END

Something's not right here - you show /traceback in the options but no traceback information is shown in the error message, I wonder if this error is happening in a different place in the code. How do you know that's where it is? Have you stepped through that section of code in the debugger and seen it step into the DO loop? If you add a PRINT of the loop variable inside the loop, does it print?

Steve - Intel Developer Support

Steve – Excellent suggestion. The problem does appear to be in the loop (see attached). The statements print *, ‘Steve Lionel suggestion’ and print *, ‘Entering forbidden loop’ are executed but the statement print *, ‘i = ‘, i does not execute. Instead, the undefined array element is accessed. I agree that something is wrong here.

Attachments: 

I'm going to try some experiments tomorrow to see if I can reproduce this, but it would be better if you could provide us a program that shows the problem. You can do it through Intel Premier Support if you like. Since you're using Aspen, see if you can cut the program down to not use Aspen but still show the error.

As a quick experiment, please add PRINT statements just before the DO loop to print the value of the start and end expressions.

Steve - Intel Developer Support

I can't reproduce this on my own, We'll need a real test case from you.

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today