Code Comments
Programming Forum and web based access to our favorite programming groups.Hello all, I've come across a code where there are jumps to the terminal statements of DO loops, and I'm wondering what they do, according to the standard. (1) do 100 i = 1, 10 . . . . . . if (. . .) go to 100 . . . . . . 100 continue If it conforms to the standard, is this equivalent with (2) do 100 i = 1, 10 . . . . . . if (. . .) go to 999 !! EXIT . . . . . . 100 continue 999 continue or (3) do 100 i = 1, 10 . . . . . . if (. . .) go to 999 !! CYCLE . . . . . . 999 continue 100 continue ? (I hope (2) and (3) are standard-conforming. :) Even in the days of F77, I had never written code like (1) because I didn't know how to interpret it, and even if I did know, I wouldn't have thought the reader of my code would always know. I'm sure this is a FAQ, but I didn't find relevent discussion in google (too many hits with keywords like "go to", "continue", "do loop"). I also tried to decipher the F77 standard (http://www.fortran.com/fortran/F77_std/rjcnf.html) but I didn't find a clue by browsing the sections of DO and GO TO. Thank you, Ryo
Post Follow-up to this messageRyo wrote: > I've come across a code where there are jumps to > the terminal statements of DO loops, and I'm wondering > what they do, according to the standard. > (1) > do 100 i = 1, 10 > . . . . . . > if (. . .) go to 100 > . . . . . . > 100 continue > If it conforms to the standard, is this equivalent with (snip of examples with GOTOs going to a statement just before and just after the loop terminating CONTINUE.) > ? (I hope (2) and (3) are standard-conforming. :) You didn't give the hard cases, which are also legal: do 100 i = 1, 10 do 100 j = 1, 10 . . . . . . if (. . .) go to 100 . . . . . . 100 continue and: do 100 i = 1, 10 . . . . . . if (. . .) go to 100 . . . . . . 100 a(i)=x I believe one relevant part of the standard, from 8.1.6.2: The range of a nonblock DO construct consists of the do-body and the following DO termination. The end of such a range is not bounded by a particular statement as for the other executable constructs (e.g., END IF); nevertheless, the range satisfies the rules for blocks (8.1.1). Transfer of control into the do-body or to the DO termination from outside the range is prohibited; in particular, it is permitted to branch to a do-term-shared-stmt only from within the range of the corresponding inner-shared-do-construct. That is, the terminating statement is part of the range of the DO, and so the GOTO does not exit the loop early. (I wonder if this is the source of the C continue statement which starts the next iteration of a loop early.) In the case of a statement terminating more than one DO loop it is inside the range of both loops. In the case of a statement other than CONTINUE terminating a DO loop, that statement is executed as part of the body of the loop, before the next iteration. Just one more example, which I do believe is illegal: do 100 i = 1, 10 . . . . . . if (. . .) go to 100 . . . . . . do 100 j = 1, 10 . . . . . . 100 continue In this case, the GOTO would be going into the range of the j loop from outside, and so would be illegal. (and I won't mention extended range of DO loops, already gone in Fortran 77) -- glen
Post Follow-up to this messageIn article <NK2dnT1YKMwH3xffRVn-qA@comcast.com>, glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote: > Just one more example, which I do believe is illegal: > > do 100 i = 1, 10 > . . . . . . > if (. . .) go to 100 > . . . . . . > do 100 j = 1, 10 > . . . . . . > 100 continue > > In this case, the GOTO would be going into the range of the j > loop from outside, and so would be illegal. You are correct that this is illegal (though in my first skim, I missed the important first 2 letters of the word "illegal"). However, I'll note that I have worked with old programs that used this abominable and nonstandard practice. I've had to help convert said programs so that they actually compiled and worked correctly on compilers that didn't support this as an extension. Painful. My pains were exacerbated by the problem that the compiler I was working with at the time didn't give an error message for it either - it just compiled it without warning into code that didn't do anything sensible. What once somewhat upset me was that it took quite a lot of work to explain to a particular compiler vendor representative that this wasn't standard. That discussion took place on this newsgroup (somewhere around 2 decades ago). I'll avoid names even though the particular rep hasn't been here in an age (and the vendor in question is still around but seems close to going under IMO :-)). It turns out that the vendor rep had assumed that he knew what the rage of a DO loop meant. Simple enough concept, right? Except that his definition didn't match the one in the standard. IIRC, he thought that DO loop ranges were non-overlapping so that the range of a DO loop excluded the ranges of any nested loops, or some such thing. It didn't actually hold together as a consistent definition, but that's what lead him down the wrong road. -- Richard Maine | Good judgment comes from experience; email: my first.last at org.domain | experience comes from bad judgment. org: nasa, domain: gov | -- Mark Twain
Post Follow-up to this messageRichard E Maine wrote: (snip of illegal GOTO to the terminating statement of a DO from outside of that DO) > You are correct that this is illegal (though in my first skim, I missed > the important first 2 letters of the word "illegal"). > However, I'll note that I have worked with old programs that used this > abominable and nonstandard practice. I've had to help convert said > programs so that they actually compiled and worked correctly on > compilers that didn't support this as an extension. Painful. My pains > were exacerbated by the problem that the compiler I was working with at > the time didn't give an error message for it either - it just compiled > it without warning into code that didn't do anything sensible. (snip) One I remember seeing once was an FFT routine that had many nested DO loops from 1 to 2, for the radix 2 transform. There were then IF statements to enter the appropriate inner DO, and exit before the termination of that DO. Most likely illegal, but it might work if the compiler doesn't optimize too much. Leaving out the IF around the termination, even though it is only CONTINUE statements, seems much more likely to fail. Definitely NOT extended range of the DO. -- glen
Post Follow-up to this messageHi, I tried myself in two compilers (compaq and g95), and get the expected result: do 100 i = 1, 2 goto 100 do 100 j = 3, 4 100 write(*,*) i, j is illegal. do 100 i = 1, 2 do 100 j = 3, 4 goto 100 100 write(*,*) i, j is legal. So, I have the question, can one say that the "100 write..." is inside the inner loop, but not directly inside the outer loop?
Post Follow-up to this message"FJRA" <a19980403@pucp.edu.pe> writes: ... > do 100 i = 1, 2 > do 100 j = 3, 4 > goto 100 > 100 write(*,*) i, j ... > So, I have the question, can one say that the "100 write..." is inside > the inner loop, but not directly inside the outer loop? Well... I suppose that one can say many things, and I wouldn't call that incorrect. I just don't think that "directly inside" is a very useful concept here. It is inside both loops - that part is easy. The standard's technical term is "in the range of", but I'd accept "inside" as a decent informal shorthand for that. I just can't think of a place where one would use the concept of "directly inside" very well. But if you find the concept useful (and perhaps define it as meaning inside, but not inside of a nested loop), then I'd agree with your application of that definition to this question. Do loops like this to be confusing in subtle ways. The problem is with ending on statements that actually "do" something, as opposed to continue or enddo, which just mark the end of the loop. To me the confusing part is that the statement label sort of stands for two different places. If you goto the statement label, then you are going to a point before that statement; the write (in this case) gets executed after the goto. But in its role as a DO loop end, the 100 in some sense stands for a position after the write statement. If the DO loop ends with a continue or enddo, then there basically isn't anything to execute between the beginning of the statement and the end of it, so the two points are the same.... if that makes sense to anyone other than me. Do/enddo is so much conceptually simpler. A little more verbose, yes, but conceptually simpler. -- Richard Maine email: my last name at domain domain: summertriangle dot net
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.