Alternate return is a facility to control the flow of execution on return from a subroutine. It is often used as a form of error handling:
real x
call sub(x, 1, *100, *200)
print*, "Success:", x
stop
100 print*, "Negative input value"
stop
200 print*, "Input value too large"
stop
end
subroutine sub(x, i, *, *)
real, intent(out) :: x
integer, intent(in) :: i
if (i<0) return 1
if (i>10) return 2
x = i
end subroutine
The alternate return is marked by the arguments *
in the subroutine dummy argument list.
In the call
statement above *100
and *200
refer to the statements labelled 100
and 200
respectively.
In the subroutine itself the return
statements corresponding to alternate return have a number. This number is not a return value, but denotes the provided label to which execution is passed on return. In this case, return 1
passes execution to the statement labelled 100
and return 2
passes execution to the statement labelled 200
. An unadorned return
statement, or completion of subroutine execution without a return
statement, passess execution to immediately after the call statement.
The alternate return syntax is very different from other forms of argument association and the facility introduces flow control contrary to modern tastes. More pleasing flow control can be managed with return of an integer "status" code.
real x
integer status
call sub(x, 1, status)
select case (status)
case (0)
print*, "Success:", x
case (1)
print*, "Negative input value"
case (2)
print*, "Input value too large"
end select
end
subroutine sub(x, i, status)
real, intent(out) :: x
integer, intent(in) :: i
integer, intent(out) :: status
status = 0
if (i<0) then
status = 1
else if (i>10)
status = 2
else
x = i
end if
end subroutine