Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29638 Discussions

Problem with arrays boundes in condition operator

digger
Beginner
2,116 Views
When I write something like thet:
IF(NUM.GT.0.AND.ARR(NUM).EQ.200) IIS=NN2
program crashed with out of range exception (option is on).
Program perfectly worked with watcom fortran, CVF, G77. Is this a IFC's problem?
0 Kudos
9 Replies
Steven_L_Intel1
Employee
2,116 Views
No, it's your problem. Your code depends on the array index not being evaluated if the .GT. is false. The Fortran standard does not allow you to make that assumption - the compiler can evaluate the entire expression in any order and completeness it wants to. You may get lucky, or you may not...
Use nested IF-THEN to protect the array reference.
0 Kudos
digger
Beginner
2,116 Views
This F77 code worked in the course of 20 years on the different compilers and computers and now prove defective? Very strange! Where I can read these standards?
0 Kudos
Steven_L_Intel1
Employee
2,116 Views
Strange it may be, but the code is still wrong. What order of evaluation you get is entirely dependent on what the compiler feels like doing, which can depend on optimization choices.
The relevant text in the standard is this:
"Once the interpretation of an expression has been established in accordance with those rules [about the definition of logical operations], the processor may evaluate any other expression that is logically equivalent, provided that the integrity of parentheses in any expression is not violated."
0 Kudos
Intel_C_Intel
Employee
2,116 Views
Out of interest then Steve, would this work:
Code:
IF((NUM.GT.0).AND.ARR(NUM).EQ.200) IIS=NN2
0 Kudos
sabalan
New Contributor I
2,116 Views
I think you'd better to write it this way:
	IF (NUM .GT. 0) Then
	  IF (ARR(NUM) .EQ. 200) IIS=NN2
	END IF
Sabalan.
0 Kudos
Intel_C_Intel
Employee
2,116 Views
Sabalan - yeah I appreciate that, but I was wondering if you could force the order of evaluation using the 'integrity of parentheses'. However, I can see that wouldn't make any difference unless the compiler would short-circuit anyway.
0 Kudos
Steven_L_Intel1
Employee
2,116 Views
No, that would not work. The parentheses make sure that the interpretation is what you want - for example, A * B + C is not the same as A * (B + C). The parentheses define what the subexpressions are, but do not specify, in your example, which operand of the .AND. gets evaluated first nor even if they both or neither get evaluated. The compiler can reorder things and evaluate fully or partially as it desires, as long as it comes up with an equivalent expression.
Nested IF-THEN is the only way to deal with this in Fortran today. There are proposals for some (far off) future edition of the standard to add operators such as .ANDTHEN. and .ORELSE.
This problem seems to hit people coming from C the most, as C does specify not only the order of evaluation but the notion of "short-circuiting". Fortran does not. A given compiler may choose to apply C's rules, but a program which depends on it doing so is non-standard and non-portable. More often, you just "get lucky" because the compiler chose to do it the way you wanted. When I was working on CVF, we would get a lot of complaints about this exact same issue - it all depended on what mood the optimizer was in that day...

Message Edited by sblionel on 07-28-2004 10:51 AM

0 Kudos
TimP
Honored Contributor III
2,116 Views
C allows short-circuiting only for operators like && and ||, not for & and |. Fortran doesn't have such a distinction, and doesn't rule out treating .AND. and .OR. somewhat like the bit-wise C operators. There's no standard which says Fortran has to be implementedthe same asf2c. Even g77 can't be counted on for the same results as f2c, if you depend on unspecified order of evaluation.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,116 Views
This is pretty much of a faq on comp.lang.fortran. The point is, the only way to write it correctly is via nested IF-statements, as Sabalan wrote it. There's no way to workaround it even if user-defined operators come into play (e.g. you candefine your own ".and_then." operator, but you still cannot prevent the array-bound problematic expression to be evaluated; ditto with parens).
There was aninterestingproposal in discussion on c.l.f, namely to introduce "short-circuiting" operator .and_then.but it didn't make it to 2003 Standard.
Jugoslav
0 Kudos
Reply