- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there
Could someone let me know if it is possible to go to a specific line of a program from a subroutine.
For example, the following program is to print only positive inputted numbers, but error #6323 occurs in compiling.
PROGRAM test01
1 READ*, x
CALL a(x)
GO TO 1
END PROGRAM test01
subroutine a(x)
if (x.lt.0) go to 1
print*, x
return
end
TEST01.F(7): error #6323: This label is not defined in this scoping unit. [1]
if (x.lt.0) go to 1
---------------------^
Many thanks
Hamid
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there
Could someone let me know if it is possible to go to a specific line of a program from a subroutine.
There is something called "ALTERNATE RETURN" Look it up in the help.
Opinion varies as to it being a good or bad feature. Personally I consider it very bad.
Modifying your code slighlty :-
PROGRAM test01
1 READ*, x
CALL a(x,*1, *999) ! The *1, *2are the alternate returns
GO TO 1
999 continue
END PROGRAM test01
subroutine a(x, *, *) ! Ugly * in argument list
if (x.lt.0)return 1 ! return to the label identified by the
! first alternate return
if (x.eq.0)return2 ! return to the label identified by the
! second alternate return
print*, x
return
end
Les
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there
Could someone let me know if it is possible to go to a specific line of a program from a subroutine.
For example, the following program is to print only positive inputted numbers, but error #6323 occurs in compiling.
PROGRAM test01
1 READ*, x
CALL a(x)
GO TO 1
END PROGRAM test01
subroutine a(x)
if (x.lt.0) go to 1
print*, x
return
end
TEST01.F(7): error #6323: This label is not defined in this scoping unit. [1]
if (x.lt.0) go to 1
---------------------^
Many thanks
Hamid
The label 1 of program test01 is outside the scope of subroutine a.
Consider changing subroutine a into a function a that returns an error code or logical (.true. or .false.) then testing the return value after evocation.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there
Could someone let me know if it is possible to go to a specific line of a program from a subroutine.
There is something called "ALTERNATE RETURN" Look it up in the help.
Opinion varies as to it being a good or bad feature. Personally I consider it very bad.
Modifying your code slighlty :-
PROGRAM test01
1 READ*, x
CALL a(x,*1, *999) ! The *1, *2are the alternate returns
GO TO 1
999 continue
END PROGRAM test01
subroutine a(x, *, *) ! Ugly * in argument list
if (x.lt.0)return 1 ! return to the label identified by the
! first alternate return
if (x.eq.0)return2 ! return to the label identified by the
! second alternate return
print*, x
return
end
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Opinion varies as to it being a good or bad feature. Personally I consider it very bad.
I don't think that the "opinion varies" -- the opinion that it's bad is fairly equivocal :-).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Alas if the person who wrotethe code that I have modified since I started work here,is still out there and coding then at least one person likes alternate return. :-(
(BTW I see we are still without "smileys")
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The label 1 of program test01 is outside the scope of subroutine a.
Consider changing subroutine a into a function a that returns an error code or logical (.true. or .false.) then testing the return value after evocation.
Jim Dempsey
Many thanks Jim, but I have to use a subroutine
Hamid
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is something called "ALTERNATE RETURN" Look it up in the help.
Opinion varies as to it being a good or bad feature. Personally I consider it very bad.
Modifying your code slighlty :-
PROGRAM test01
1 READ*, x
CALL a(x,*1, *999) ! The *1, *2are the alternate returns
GO TO 1
999 continue
END PROGRAM test01
subroutine a(x, *, *) ! Ugly * in argument list
if (x.lt.0)return 1 ! return to the label identified by the
! first alternate return
if (x.eq.0)return2 ! return to the label identified by the
! second alternate return
print*, x
return
end
Les
Many thanks Les
Could you explain why you consider it a very bad idea. I do need it in the code I am writing.
Hamid
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Many thanks Les
Could you explain why you consider it a very bad idea. I do need it in the code I am writing.
Hamid
Ugly, Readability, Maintainability, ...
One way to avoid alternate return is to use a status return value :
subroutine foo(x,istat)
istat = 0
if (x .lt. 0) istat = 1
if (x .eq. 0) istat = 2
etc.
if (istat .ne. 0) return
... do something ...
end subroutine foo
For more complex variations on the values of istatin your main you would use a SELECT CASE on istat after calling foo. Or you could just use simple if statements
call foo(x,istat)
if (istat .eq. 1) go to 1
if (istat .eq. 2) go to 999
etc...
In your simplified example you could write it as
program main
integer :: istat
real :: x
istat = 0
DO WHILE (istat==0)
read *,x
call foo(x,istat)
ENDDO
subroutine foo(x, istat)
real :: x
integer :: istat
istat = 0
if (x.eq.0) istat=1 ! Setthefinish flag
if (x.gt.0) then
print *,x
endif
return
end subroutine foo
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ugly, Readability, Maintainability, ...
One way to avoid alternate return is to use a status return value :
subroutine foo(x,istat)
istat = 0
if (x .lt. 0) istat = 1
if (x .eq. 0) istat = 2
etc.
if (istat .ne. 0) return
... do something ...
end subroutine foo
For more complex variations on the values of istatin your main you would use a SELECT CASE on istat after calling foo. Or you could just use simple if statements
call foo(x,istat)
if (istat .eq. 1) go to 1
if (istat .eq. 2) go to 999
etc...
In your simplified example you could write it as
program main
integer :: istat
real :: x
istat = 0
DO WHILE (istat==0)
read *,x
call foo(x,istat)
ENDDO
subroutine foo(x, istat)
real :: x
integer :: istat
istat = 0
if (x.eq.0) istat=1 ! Setthefinish flag
if (x.gt.0) then
print *,x
endif
return
end subroutine foo
Les
Much appreciated your kind response.
Hamid
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'll also note that alternate returns have been removed from the Fortran language standard.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page