forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Why this is illegal?

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General
View previous topic :: View next topic  
Author Message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Tue Mar 20, 2018 10:13 am    Post subject: Why this is illegal? Reply with quote

Code:
iEnd = 2       
  do i=1,iEnd
    if(i.eq.2) iEnd=4
    print*,i
  enddo
end


Last i it prints is i=2 instead of i=4. I'd understand that do loop refused to change do loop variable i but what in Fortran world would be hurt by dynamically changing doo loop min and max values???? Is this again the Fortran Standard mental sheez?
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1886

PostPosted: Tue Mar 20, 2018 10:48 am    Post subject: Reply with quote

The loop count is calculated just once, when the DO construct is begun. Subsequent changes to the variables used in the <start>, <end> and <increment> expressions do not affect the loop count. However, such changes can affect whether a premature EXIT, or a CYCLE statement, are executed.

See davidb's post of Feb. 20 in http://forums.silverfrost.com/viewtopic.php?t=3682 .

Over the years, working with codes that were decades old, I have seen DO index variables abused quite a bit. In one code, the DO index was passed as an argument in a subroutine call inside the loop, and the subroutine changed the value of the index variable.

If you want a free-wheeling DO loop, you may use a

DO WHILE(<condition>)
<statements>
END DO

block, or a plain

DO
<statements>
END DO

construct.

Quote:
... but what in Fortran world would be hurt by dynamically changing do loop min and max values?

I can imagine Col. Cathcart asking Yossarian such a question (see Heller's novel "Catch-22" ).
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Tue Mar 20, 2018 1:11 pm    Post subject: Reply with quote

If you look at this example of DO loop which is a sibling of my example above with "classical" DO loop of Fortran-66 era or even before that you can see that its finishing condition is calculated every time with no problems.
Code:
i=0
iEnd = 4       
  do while (i <= iEnd)
    i=i+1
    if(i.eq.2) iEnd=2
    print*,i
  enddo
end


So nothing prohibits classical DO loop to do the same. Actually not doing that looks counterintuitive, too over-restricting and obsolete.
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1886

PostPosted: Tue Mar 20, 2018 1:35 pm    Post subject: Re: Reply with quote

DanRRight wrote:
If you look at this example of DO loop which is a sibling of my example above with "classical" DO loop of Fortran-66 era or even before that you can see that its finishing condition is calculated every time with no problems.
Code:
i=0
iEnd = 4       
  do while (i <= iEnd)
    i=i+1
    if(i.eq.2) iEnd=2
    print*,i
  enddo
end


So nothing prohibits classical DO loop to do the same. Actually not doing that looks counterintuitive, too over-restricting and obsolete.


"Nothing"? Any Fortran standard newer than Fortran-66 does!

The Fortran Standard (77, 95, 2003, ...) is quite explicit about how the DO loop with loop control of the type <int_expr1>, <int_expr_2>[, <int_expr_3] is to be executed. Please read 8.1.4.4 of the Fortran 95 standard, or read DavidB's post, where he described the operation of this type of DO.

Old (66, IV, II) Fortran compilers, of course, had a different view, and some 80's and 90's compilers had a switch to replicate the old behavior. FTN95 still has the /DO1 option to support the "at least one-trip DO". We should not write code today that requires that kind of treatment.
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Wed Mar 21, 2018 1:18 pm    Post subject: Reply with quote

Mecej4, DavidB did not discuss explicitly possibility of dynamic changing start and end of DO loop. We even discussed here ones the possibility of dynamic changing DO loop variable i like in

DO i=iStart, iEnd

and there were no strict opposition for that besides the rulings of the Standard. Heard there exist other than Fortran compilers which allow dynamically changing even all three: i, iStart and iEnd. I'd probably agree with not allowing for using floating point numbers for them as this has hidden problem with the rounding of FP numbers but still do not see reasons for the restrictions we are discussing above
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Wed Mar 21, 2018 2:11 pm    Post subject: Reply with quote

Dan,

The change to DO loop cycles was one of the more significant changes at F77. It has become a significant property of Fortran DO loops.
If you want to vary the loop cycles, you have "DO while" or use "DO" and manage the loop variable and exit.

John
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1886

PostPosted: Wed Mar 21, 2018 2:18 pm    Post subject: Re: Reply with quote

DanRRight wrote:
Mecej4, DavidB did not discuss explicitly possibility of dynamic changing start and end of DO loop. We even discussed here ones the possibility of dynamic changing DO loop variable i like in

DO i=iStart, iEnd

and there were no strict opposition for that besides the rulings of the Standard. Heard there exist other than Fortran compilers which allow dynamically changing even all three: i, iStart and iEnd.

How on earth can you change the start after the DO loop has been started?

The for loop of C does what you seem to want. You can also write in Fortran:

i = iStart; DO WHILE (i <= IEND); ...I = ..; IEND = ..; ... ; END DO

Try the following example, which is a modification of one that I found on the Web.
Code:
      program SmallLoopWrong
        integer i,j
        j=10
        do i = 1, j
           write (*,*) i
           if (i .eq. 10) then
              j = i+1              ! ERROR. Programmer wants an extension!
           end if
        end do
        print *,'i,j = ',i,j
      end

How many lines should the program print?

Try various compilers on this program. What does running the program give you?

Try to get a compiler to help you with locating this "bug".
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Wed Mar 21, 2018 3:59 pm    Post subject: Re: Reply with quote

mecej4 wrote:

How on earth can you change the start after the DO loop has been started?


Same as iEnd above Smile

Code:
iStart = 1       
iEnd   = 4       
  do i=iStart, iEnd
    if(i.eq.2) iStart=4
    print*,i
  enddo
end


JohnCampbell wrote:
Dan,

The change to DO loop cycles was one of the more significant changes at F77. It has become a significant property of Fortran DO loops.
If you want to vary the loop cycles, you have "DO while" or use "DO" and manage the loop variable and exit.

John,
Such damn inconsistences that some DO constructs allow changing its operation conditions and some don't caused me one week of loss for unexplainable errors over 20 years
Back to top
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Wed Mar 21, 2018 5:38 pm    Post subject: Reply with quote

The standard says:

"The number of iterations of a loop may be determined at the beginning of execution of the DO construct, or may be left indefinite ("DO forever" or DO WHILE). In either case, an EXIT statement (8.1.4.4.4) anywhere in the DO construct may be executed to terminate the loop immediately."

It also says:

"Except for the incrementation of the DO variable that occurs in step (3), the DO variable shall neither be redefined nor become undefined while the DO construct is active."

The standard doesn't forbid changing m1, m2, or m3 in the loop as far as I know, but such changes don't affect the number of loop iterations. They can't because the number of iterations is calculated at the beginning, before the loop is executed.

Knowing the number of iterations up front allows optimizing compilers to optimize the loop effectively (techniques as loop-unrolling, swapping loops, merging loops).

The loop

Code:

do i=1,m2
   <body of loop>
end do


is equivalent to:

Code:

i = 1
count = max(m2, 0)  ! <-- loop is executed count times
c = count
10 if (c .eq. 0) goto 20
   <body of loop>
   c = c - 1
   i = i + 1
   goto 10
20 continue


A more general equivalence is given in the post mecej4 refers to.

As John points out you can do all manner of complicated loops if you use the indefinite "DO forever" type with EXIT. But don't expect much optimization in such cases.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Thu Mar 22, 2018 9:03 am    Post subject: Reply with quote

DavidB,

Great, since the only serious negative objection from dynamic changing iStart, iEnd and iStep (and probably even loop variable i itself DO i=iStart, iEnd, iStep) could potentially be difficulties of compiler optimization (not always necessarily so, sure by far not) then from this follows pretty satisfactory solution for both sheep and wolves:

1) Users who change these variables dynamically get the compiler warning "Dynamically changing DO loop controlling variables may prevent compiler optimization"

2) As an extension of Standard, all DO loop controlling variables are not just calculated ones before the loop start but can be changed dynamically at any moment during its run.

How about that?
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1886

PostPosted: Thu Mar 22, 2018 10:50 am    Post subject: Re: Reply with quote

Dan, the title of the thread is misleading. There is nothing "illegal" about the short example code that you started with. Your complaint is really about how the loop is executed. You expect different behavior than what the standard prescribes.

If you want your request to be taken seriously, you will need to do far more work to prepare and justify your request. You will need to consider all possible circumstances and variations, write down a precise and complete prescription of how the loop ought to behave, why your proposed interpretation of DO would be better than the present behavior, and explain why you think that your requested behavior should be imposed on everyone. You should also be prepared to do a cost versus benefit analysis, and to justify why you do not want to use the already available DO WHILE facility.

DanRRight wrote:
... then from this follows pretty satisfactory solution for both sheep and wolves:
...
How about that

Consider this:
Code:

iDan = iWolf
do i=iBeg, iEnd
...
   if(i.eq.2)iDan = iSheep
...
end do


and the value of iDan controls how the loop behaves, i.e., sheepish or lupine.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Mar 22, 2018 10:52 am    Post subject: Re: Reply with quote

DanRRight wrote:
Such damn inconsistences that some DO constructs allow changing its operation conditions and some don't caused me one week of loss for unexplainable errors over 20 years

Dan,
Your original post has been illegal for 41 years !!
There is a Australian cinema quote from "The Castle" that could apply here : “Tell him he’s dreamin'”
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1886

PostPosted: Thu Mar 22, 2018 11:05 am    Post subject: Reply with quote

John, if we let Dan build castles in the air, he could one day demand that the optional increment expression (the i3 in DO i = i1, i2, i3) should be allowed to be changed in the loop; if that change involves i3 = -i3, Dan will have created an UNDO loop lurking inside a DO loop!
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Thu Mar 22, 2018 11:24 pm    Post subject: Re: Reply with quote

JohnCampbell wrote:

Your original post has been illegal for 41 years !!


This is why when i asked my colleagues how their different compilers behave in this case they responded "Forget that dinosaurian Fortran. iEnd is just a usual variable. Of course in our case it can be changed (though not recommended)". This is exactly what i propose, no one will be hurt. If you don't want it - do not use it, all will stay the same besides it's me who decide not somebody else.

The thick fog is actually much thinner if any then Mecej4 have been painting: the Standard with its "The number of iterations of a loop may be determined at the beginning of execution of the DO construct, or may be left indefinite" does say MAY but not say that it MUST. So i'd go ahead and fix it returning to "classic" DO loop some common sense waiting for 41 years.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group