- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
DO i=1,100
DO j=1,100
! I want to stop scanning if I meet some criterion - -
! I want to jump out of BOTH levels
! normally, I would have to use a GO TO:
if( A(I,J).lt.100)GO TO 40
! an exit does NOT jump out of both levels.
END DO
END DO
40 ! place I am jumping to
Apparently our current Fortran does not have anything like EXIT 40, where you can tell it WHERE to exit to.
I know we're not supposed to use GO TOs if possible, but what's the alternative here?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
DO i=1,100
DO j=1,100
! I want to stop scanning if I meet some criterion - -
! I want to jump out of BOTH levels
loop1: do....
loop2: do..
if() exit loop1
enddo loop2
enddo loop1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The above works, except you have to be aware that should the inner loop have !$OMP PARALLEL DO then you cannot exit the outer loop from within the inner parallel loop. For that consider using a shared flag
error = .false.
loop1: do....
!$OMP PARALLEL DO SHARED(error)
loop2: do..
if(.not. error) error = (error detection expression)
if(error)exit
enddo loop2
!$OMP ENDPARALLEL DO
if(error) exit
...
enddo loop1
>> if(.not. error) error = (error detection expression)
The above protectes agains one thread setting error to .true. and another thread setting error to .false.
All threads exit inner loop when any thread detects error, thenouter loop thread exits outer loop
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The above works, except you have to be aware that should the inner loop have !$OMP PARALLEL DO then you cannot exit the outer loop from within the inner parallel loop. For that consider using a shared flag
error = .false.
loop1: do....
!$OMP PARALLEL DO SHARED(error)
loop2: do..
if(.not. error) error = (error detection expression)
if(error)exit
enddo loop2
!$OMP ENDPARALLEL DO
if(error) exit
...
enddo loop1
>> if(.not. error) error = (error detection expression)
The above protectes agains one thread setting error to .true. and another thread setting error to .false.
All threads exit inner loop when any thread detects error, thenouter loop thread exits outer loop
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Think of it as structure exception handling.
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quite; judicious use of GOTOs can substantially reduce the length of complicated control structures where thereare several levels of IF-THEN and DO-ENDDO structures to break out of.
The downside of GOTOs, as far as I know,is that they can make the flow of a program difficult to follow. If this is addressed, for example by:
- never jumping more than ~20 lines of code
- at the 'destination', putting a comment to explain where the program may have jumped from
...then there seems no reason not to use them if they're the best tool for the job.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>The downside of GOTOs, as far as I know,is that they can make the flow of a program difficult to follow.
And the upside of GOTO is they can make the flow of a program easy to follow.
Like all statements it can be abused, as well as be used effectively.
As mentioned earlier in this thread, you can use alternate means such as "exit LoopName", "cycle LoopName", while at other times the clearest way to express the flow is with use of "GOTO nnn" or "GOTO SomeName". I recommend using the name tag method as opposed to numeric tag, and choose an appropriate name.
Most of the "tweets" on problems with goto evolved around earlier implementations of C were GOTOcould go anywhere without regard to the consequences of scoping rules. And in the process trash the stack, not initialize local scoped variables etc... Fortran doesn't have nested scopes ({...}) so most of the arguments with respect to C do not hold for use in Fortran.
Those problems are fixed now in C++ and all the reasons of substance for banning use of goto are moot. This leaves style as the only arguing point. You cannot goto to enter a scope, gotos that exit a scope also cleanup implicitly (call dtor's, pop scope local variables etc...)
>> Quite; judicious use of GOTOs can substantially reduce the length of complicated control structures where thereare several levels of IF-THEN and DO-ENDDO structures to break out of.
Yes, In Fortran, as well as C++, avoidance of GOTO may require you to intoduce convolutions into an otherwise simple routine.
Jim Dempsey
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page