Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go code doesn't compile without an unreachable return statement

Tags:

go

Here is the program to find the factorial of a number in Go:

func factorial(x uint) uint {
    if x == 0 {
        return 1
    }

    return x * (factorial(x - 1))
}

The output for this function when called on input 5 is 120. However, if I add an else statement I get an error.

func factorial(x uint) uint {
    if x == 0 {
        return 1
    } else {
        return x * (factorial(x - 1))
    }
}

Error : function ends without a return statement

I added a return at the end :

func factorial(x uint) uint {
    if x == 0 {
        return 1
    } else {
        return x * (factorial(x - 1))
    }
    fmt.Println("this never executes")
    return 1
}

and I get back the expected output of 120.

Why would the second case cause an error? Why in the third case even though the function never reaches the last return 1, it computes the correct output?

like image 435
sreeprasad Avatar asked Nov 22 '12 15:11

sreeprasad


People also ask

Why is code unreachable after return statement?

The JavaScript warning "unreachable code after return statement" occurs when using an expression after a return statement, or when using a semicolon-less return statement but including an expression directly after.

Does unreachable code compile?

If any code can not be executable in any of the possible flows, then it is called unreachable code. Unreachable code in java is a compile time error. Look at the following example.

Why is unreachable code an error?

In computer programming, unreachable code is part of the source code of a program which can never be executed because there exists no control flow path to the code from the rest of the program.

What is unreachable code in angular?

It usually happens when you put some code after a return statement, or when you have a return inside of an if statement and you forget the else code.


1 Answers

This is a well known problem of the compiler.

There is even an issue logged : http://code.google.com/p/go/issues/detail?id=65

In the words of one of the authors of the Go language:

The compilers require either a return or a panic to be lexically last in a function with a result. This rule is easier than requiring full flow control analysis to determine whether a function reaches the end without returning (which is very hard in general), and simpler than rules to enumerate easy cases such as this one. Also, being purely lexical, the error cannot arise spontaneously due to changes in values such as constants used in control structures inside the function.

-rob

From another comment in golang-nuts, we can infer it's not going to be "fixed" soon :

It's not a bug, it's a deliberate design decision.

-rob

Note that other languages like Java have rules allowing this else.


March 2013 EDIT - It just got changed in Go1.1 :

Before Go 1.1, a function that returned a value needed an explicit "return" or call to panic at the end of the function; this was a simple way to make the programmer be explicit about the meaning of the function. But there are many cases where a final "return" is clearly unnecessary, such as a function with only an infinite "for" loop.

In Go 1.1, the rule about final "return" statements is more permissive. It introduces the concept of a terminating statement, a statement that is guaranteed to be the last one a function executes. Examples include "for" loops with no condition and "if-else" statements in which each half ends in a "return". If the final statement of a function can be shown syntactically to be a terminating statement, no final "return" statement is needed.

Note that the rule is purely syntactic: it pays no attention to the values in the code and therefore requires no complex analysis.

Updating: The change is backward-compatible, but existing code with superfluous "return" statements and calls to panic may be simplified manually. Such code can be identified by go vet.

And the issue I mentioned is now closed with status "Fixed".

like image 107
Denys Séguret Avatar answered Jan 01 '23 00:01

Denys Séguret