9.7 Return Value

Non-void functions must have a return statement that returns an appropriately typed expression. If the expression in a return statement does not have the same type as the return type declared for the function, a compile-time error is raised.

Void functions may use return only without an argument, but return statements are not mandatory.

Return Guarantee Required

Unlike C++, Stan enforces a syntactic guarantee for non-void functions that ensures control will leave a non-void function through an appropriately typed return statement or because an exception is raised in the execution of the function. To enforce this condition, functions must have a return statement as the last statement in their body. This notion of last is defined recursively in terms of statements that qualify as bodies for functions. The base case is that

  • a return statement qualifies,

and the recursive cases are that

  • a sequence of statements qualifies if its last statement qualifies,
  • a for loop or while loop qualifies if its body qualifies, and
  • a conditional statement qualifies if it has a default else clause and all of its body statements qualify.

These rules disqualify

real foo(real x) {
  if (x > 2) return 1.0;
  else if (x <= 2) return -1.0;
}

because there is no default else clause, and disqualify

real foo(real x) {
  real y;
  y = x;
  while (x < 10) {
    if (x > 0) return x;
    y = x / 2;
  }
}

because the return statement is not the last statement in the while loop. A bogus dummy return could be placed after the while loop in this case. The rules for returns allow

real log_fancy(real x) {
  if (x < 1e-30)
    return x;
  else if (x < 1e-14)
    return x * x;
  else
    return log(x);
}

because there’s a default else clause and each condition body has return as its final statement.