Theres is a legacy code we have to compile in Linux and Windows.
in Linux we have ifort 15 and in Windows ifort 11, and the project is rather big, so code modification will be the last option
our Problem is in the following IF, for example:
INTEGER VECTOR(10) DO I=1,10 IF ( I .LT.10 .AND. VECTOR(I+1) .GT. 0) THEN ! do something END IF ENDDO
The classic IF Lazy Evaluation : If the first condition is false, in Linux , the rest will be not evaluated , therefore, VECTOR(11) will be not evaluated. In Windows, however, the same code produces the expected out of bound error: forrtl: severe Subcript #1 of Array VECTOR has value 11
I am not aware of the details , I think we had another Compiler in Windows, which didn't have this behavior, and the code was developed that way.
Of course this works everywhere
INTEGER VECTOR(10) DO I=1,10 IF ( I .LT.10 ) THEN IF (VECTOR(I+1) .GT. 0) THEN ! do something ENDIF END IF ENDDO
Unfortunately, our IF's are a bit more complex than that, and we have to much code to edit . Is there a flag we can use in compile time to force the same behavior in Windows as in Linux?
Yes, you found the discussion from the expert.
There is no valid Windows vs. linux tradition on such matters; in fact, the f2c script, which does follow your expectation on short-cutting compound IF, is much easier to find on old linux installations than on Windows.
By the way, although some might expect a competent optimizing compiler to take care of it, in this case it seems you should have written
In the cases where you have a relatively long complex IF expression that you want "lazy left-to-right" evaluation .AND. you do not want to add the additional THEN-ENDIF scoping statements, then you can insert a LOGICAL function that has the THEN-ENDIF qualifiers.
LOGICAL :: doIF
doIF = (I .LT. 10)
if(doIF) doIF = (VECTOR(I) .GT. 0)
! do something
endif ! Note only one endif
The simple way of correcting the code in #1 is to change the upper limit of the DO index to 9 (instead of 10). Doing so will simultaneously work in the same way as the evaluation of the equivalent code in C (with left-to-right, short-circuit evaluation) and also avoid an out of bounds access of VECTOR(11).
If you have other DO statements with IF statements in the loop where ELSE and ELSE IF(..) THEN clauses are present, fixing the code will be a bit more complicated. You could add statements in the loop such as IF(I.GT.9)CYCLE preceding statements that test VECTOR(I+1), etc.
Note that there is more urgency behind fixing the code than merely avoiding out-of-bounds subscript errors. If you compile without /CHECK:bounds, the code may make invalid memory accesses or the program can give incorrect results because incorrect branches are taken because invalid memory reads were used in selecting the branches.