|This article needs additional citations for verification. (February 2011)|
In computer programming, a return statement causes execution to leave the current subroutine and resume at the point in the code immediately after where the subroutine was called, known as its return address. The return address is saved, usually on the process's call stack, as part of the operation of making the subroutine call. Return statements in many languages allow a function to specify a return value to be passed back to the code that called the function.
return exp; (where
exp is an expression) is a statement that tells a function to return execution of the program to the calling function, and report the value of
exp. If a function has the return type void, the return statement can be used without a value, in which case the program just breaks out of the current function and returns to the calling one.
In Pascal there is no return statement. A subroutine automatically returns when execution reaches its last executable statement. Values may be returned by assigning to an identifier that has the same name as the subroutine, a function in Pascal terminology. This way the function identifier is used for recursive calls and as result holder; this is syntactically similar to an explicit output parameter. The same syntax is used in Fortran 66 and Fortran 77. In some other languages a user defined result variable is used instead of the function identifier.
Oberon (Oberon-07) has a return clause instead of a return statement. The return clause is placed after the last statement of the procedure body. This enables compile-time checking of proper return and return value from the procedure.
Some expression-oriented programming language, such as Lisp, Perl and Ruby, allow the programmer to omit an explicit return statement, specifying instead that the last evaluated expression is the return value of the subroutine.
In other cases a null value is returned if there is no explicit return statement: in Python, the value
undefined is returned.
In Windows PowerShell all evaluated expressions which are not captured (e.g., assigned to a variable, cast to void or piped to $null) are returned from the subroutine as elements in an array, or as a single object in the case that only one object has not been captured.
In Perl, a return value or values of a subroutine can depend on the context in which it was called. The most fundamental distinction is a scalar context where the calling code expects one value, a list context where the calling code expects a list of values and a void context where the calling code doesn't expect any return value at all. A subroutine can check the context using the
wantarray function. A special syntax of return without arguments is used to return an undefined value in scalar context and an empty list in list context. The scalar context can be further divided into Boolean, number, string, and various reference types contexts. Also, a context-sensitive object can be returned using a contextual return sequence, with lazy evaluation of scalar values.
Values returned by the program when it terminates are often captured by batch programs.
Return statements come in many shapes. The following syntaxes are most common:
|Language||Return Statement||If value omitted, Return|
|in C and C++, undefined behavior if function is value-returning
in PHP, returns
in Java and C#, not permitted if function is value-returning
|last statement value|
return @values; return $value; return;
or a contextual return sequence
|last statement value|
|Visual Basic .NET||
|contents of eax register (by convention)|
Multiple return statements
Languages with an explicit return statement create the possibility of multiple return statements in the same function. Whether or not that is a good thing is controversial.
Some people make sure each function has a single entry, single exit (SESE). These people argue that The use of a return statement violates structured programming: it is an unstructured exit from the function, resulting in multiple exit points, rather than the single exit point required by structured programming. It has thus been argued that one should eschew the use of the explicit return statement except at the textual end of a subroutine, considering that, when it is used to "return early", it may suffer from the same sort of problems that arise for the GOTO statement. Conversely, it can be argued that using the return statement is worthwhile when the alternative is more convoluted code, such as deeper nesting, harming readability.
Other people say that one or more "guard clauses" -- conditional "early exit" return statements near the beginning of a function -- often make a function easier to read than the alternative.
The most common problem in early exit is that cleanup or final statements are not executed – for example, allocated memory is not unallocated, or open files are not closed, causing leaks. These must be done at each return site, which is brittle and can easily result in bugs. For instance, in later development, a return statement could be overlooked by a developer, and an action which should be performed at the end of a subroutine (e.g., a trace statement) might not be performed in all cases. Languages without a return statement, such as standard Pascal don't have this problem. Some languages, such as C++ and Python, employ concepts which allow actions to be performed automatically upon return (or exception throw) which mitigates some of these issues – these are often known as "try/finally" or similar. Ironically, functionality like these "finally" clauses can be implemented by a goto to the single return point of the subroutine. An alternative solution is to use the normal stack unwinding (variable deallocation) at function exit to unallocate resources, such as via destructors on local variables, or similar mechanisms such as Python's "with" statement.
Some early implementations of languages such as the original Pascal and C restricted the types that can be returned by a function (e.g., not supporting record or struct types) to simplify their compilers.
In Java it is possible to execute code even after return statement, because the finally block of a try-catch structure is always executed. So if the return statement is placed somewhere within try or catch blocks the code within finally (if added) will be executed. It is even possible to alter the return value of a non primitive type (a property of an already returned object) because the exit occurs afterwards as well.
Cousin to return statements are yield statements: where a return causes a subroutine to terminate, a yield causes a coroutine to suspend. The coroutine will later continue from where it suspended if it is called again. Coroutines are significantly more involved to implement than subroutines, and thus yield statements are less common than return statements, but they are found in a number of languages.
- http://msdn.microsoft.com/en-us/library/sta56yeb.aspx MSDN: return Statement (C)
- http://msdn.microsoft.com/en-us/library/k68ktdwf.aspx MSDN: return Statement (C++)
- "PHP: return - Manual". PHP Manual. The PHP Group. Retrieved 26 March 2013.
- C++ Notes: Function return Statement
- Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts. "Refactoring: Improving the Design of Existing Code (Google eBook)". section "Replace Nested Conditional with Guard Clauses". 2012. p. 237, p. 250. quote: "... one exit point mentality ... I don't follow the rule about one exit point from a method."
- Kent Beck. "Implementation Patterns". 2007. "Chapter 7: Behavior", section "Guard Clause".
- "Multiple return statements"
- Fred Swartz. "Return statements and the single exit fantasy".
- The finally Block,The Java Tutorials