Concepts / Return Values and How Functions Communicate Results

Return Values and How Functions Communicate Results

A function call redirects execution from the caller to the function body, then returns to the caller after the function completes.

  • Programming

The Detour a Function Call Creates

A function call is a detour in the normal path of program execution. The program reaches a call in the caller, redirects execution into the function body, and then returns to the caller after the function completes. Understanding this detour is the foundation for tracing return values and explaining how functions communicate results to the code that called them.

The order in which functions appear in a source file is not necessarily the order in which they run. Execution starts at the main program, or at the first executable statement, and enters a function only when that function is called.

function callfunction completesCaller statementbefore the callFunction bodycalled codeCaller statementafter the call
When execution reaches a function call, where does control go before the caller continues?

Tracing the Rectangle Calculation

Consider the source-pack scenario of a program that calculates the area of a rectangle by calling a helper function. The important point is not the arithmetic itself. The important point is the movement of execution: the main program reaches the helper-function call, execution moves into the helper function, and execution returns to the main program when the helper finishes.

  1. Execution begins in the main program rather than inside the helper function merely because the helper appears earlier in the file.
  2. The main program reaches the statement that calls the rectangle-area helper function.
  3. The call redirects execution into the helper function's body.
  4. The helper function completes its work.
  5. Execution returns to the caller, allowing the main program to continue with the statement after the call.
callsreturns after completionMain programreaches the callArea helperperforms the calculationMain programcontinues after the call
What happens to execution as the main program calls the rectangle-area helper and then continues?

A function's position in the file does not make it execute immediately. A call determines when execution enters the function, and completion determines when execution returns to the caller.

How the Call Stack Finds the Return Point

The program needs to remember where it was in the caller before it enters a function. The call stack provides that memory. Each time a function is called, the program stores information about the current location, called the return address, on the call stack. When the function completes, the program removes that return address from the stack and uses it to jump back to the correct place in the caller.

save locationenter functionpop and use addressCaller locationreturn addressReturn addresssaved on call stackFunction bodyexecutes after callCaller locationexecution resumes
What information does the call stack save, and how does it identify the place where execution should resume?

The same mechanism also works when functions call other functions. Each new call pushes another return address onto the call stack. Each completed call pops one return address off. This lets the program return through nested calls in the correct order rather than losing track of earlier callers.

Following Results Back to the Caller

A function is useful to its caller because the caller can rely on the function to complete a separate piece of work and then return control. In a calculation such as the rectangle-area scenario, the work performed inside the helper produces the calculation's result. Once the helper completes, execution is back in the caller, where the program can continue using the outcome of that call.

callsproducesavailable after returnCallerrequests the calculationArea helpercalculates the areaArea resultproduced by the calculationCaller continuesafter completion
How does a result produced during a function call become available to the calling code?

When discussing a return value, trace two connected paths: the control path back to the caller and the result path from the completed function to the code that called it.

Predicting the Next Execution Point

What do you think happens?

A program is executing in its main section and reaches a call to a helper function. What executes next, and where does execution go after the helper completes?

  • The next function definition in the file, then the program stops
  • The first statement in the called function, then the caller resumes after the call
  • The statement before the call, then the function is skipped
  • All function bodies in the file, then the caller resumes
Reveal answer

Answer: The first statement in the called function executes next, and the caller resumes after the call when the function completes.

A function call redirects execution into the called function body. The call stack preserves the caller's return address, so completion can transfer execution back to the correct location. Source-file order does not determine this path.

MEDIUM

Describe the execution path for the rectangle-area scenario in five stages: starting location, call location, function location, completion, and resumption location.

Hints
  • Begin in the main program, not at the helper's position in the file.
  • Identify the statement that calls the helper.
  • Name the function body as the detour.
  • Use the return address to identify where the caller resumes.

When debugging an unexpected result, trace execution one call at a time. Mark where the caller pauses, which function begins executing, what work that function completes, and where the caller resumes. This prevents the source file's top-to-bottom appearance from misleading you about the actual execution order.

Mistakes in Execution Tracing

  • Assuming functions execute in the order in which their definitions appear in the file.

    Execution starts at the main program or first executable statement and enters a function when that function is called.

    Fix: Find the starting executable statement, then follow each function call as a redirection of execution.

  • Assuming execution remains in the caller while the called function performs its work.

    A function call redirects execution into the function body before the caller continues.

    Fix: Pause the caller at the call, trace the function body, and continue only after the function completes.

  • Ignoring the return address when tracing nested calls.

    Each call stores a return address on the call stack, and each return uses one saved address.

    Fix: Track each call as a push of a return address and each completion as a pop of one return address.

Key Takeaways

  1. A function call redirects execution from the caller into the function body.
  2. After the function completes, execution returns to the caller.
  3. The call stack stores return addresses so the program knows where to resume.
  4. Nested calls work because each call pushes a return address and each return pops one.
  5. Tracing calls and returns helps explain results and debug unexpected program behavior.

Key Takeaways

  • A function call creates a temporary detour from the caller into a function body.
  • The caller resumes after the function completes.
  • The call stack preserves return addresses and supports nested function calls.
  • Execution order follows calls, not simply the order of function definitions in the source file.
  • Tracing both control flow and the resulting value helps explain how functions communicate results.