- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
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?
Thanks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found this , so i think we have to modify our code
https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/275470
sorry for double posting !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
DO
I=1,9
3 |
IF ( VECTOR(I+1) .GT. 0) THEN |
4 |
! do something |
5 |
END IF |
6 |
|
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Alternatively
LOGICAL :: doIF
...
doIF = (I .LT. 10)
if(doIF) doIF = (VECTOR(I) .GT. 0)
if(doIF) THEN
! do something
endif ! Note only one endif
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page