- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Out of interest then Steve, would this work:
Code:
IF((NUM.GT.0).AND.ARR(NUM).EQ.200) IIS=NN2
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page