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