Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing return statement in a non-void method compiles

Tags:

java

c#

oop

People also ask

What happens if you forget the return statement in a non-void function?

You may or may not use the return statement, as there is no return value. Even without the return statement, control will return to the caller automatically at the end of the function.

How do I fix a missing return statement?

How to resolve the error? In order to solve the missing return statement error, we simply need to add the return statement to the method just like to the one we did in case one. So, we will return the some value of the same type which we used before the name like as: public static String checkNumber( int number) {

What do non-void methods return?

Calling non-void Methods Since a non-void method always returns a value, this value has to be stored in a variable, printed, or returned to a Java control structure or another method. Here are some examples. The method call can be in an assignment statement.

What does it mean when it says missing return statement?

“missing return statement” The “missing return statement” message occurs when a method does not have a return statement. Each method that returns a value (a non-void type) must have a statement that literally returns that value so it can be called outside the method.


Why would a language allow us to have a non-void method having an infinite loop and not returning anything?

The rule for non-void methods is every code path that returns must return a value, and that rule is satisfied in your program: zero out of zero code paths that return do return a value. The rule is not "every non-void method must have a code path that returns".

This enables you to write stub-methods like:

IEnumerator IEnumerable.GetEnumerator() 
{ 
    throw new NotImplementedException(); 
}

That's a non-void method. It has to be a non-void method in order to satisfy the interface. But it seems silly to make this implementation illegal because it does not return anything.

That your method has an unreachable end point because of a goto (remember, a while(true) is just a more pleasant way to write goto) instead of a throw (which is another form of goto) is not relevant.

Why doesn't the compiler even warn about returning something?

Because the compiler has no good evidence that the code is wrong. Someone wrote while(true) and it seems likely that the person who did that knew what they were doing.

Where can I read more about reachability analysis in C#?

See my articles on the subject, here:

ATBG: de facto and de jure reachability

And you might also consider reading the C# specification.


The Java compiler is smart enough to find the unreachable code ( the code after while loop)

and since its unreachable, there is no point in adding a return statement there (after while ends)

same goes with conditional if

public int get() {
   if(someBoolean) {   
     return 10;
   }
   else {
     return 5;
   }
   // there is no need of say, return 11 here;
}

since the boolean condition someBoolean can only evaluate to either true or false, there is no need to provide a return explicitly after if-else, because that code is unreachable, and Java does not complain about it.


The compiler knows that the while loop will never stop executing, hence the method will never finish, hence a return statement is not necessary.


Given your loop is executing on a constant - the compiler knows that it's an infinite loop - meaning the method could never return, anyway.

If you use a variable - the compiler will enforce the rule:

This won't compile:

// Define other methods and classes here
public int doNotReturnAnything() {
    var x = true;

    while(x == true) {
        //do something
    }
    //no return statement - won't compile
}

The Java specification defines a concept called Unreachable statements. You are not allowed to have an unreachable statement in your code (it's a compile time error). You are not even allowed to have a return statement after the while(true); statement in Java. A while(true); statement makes the following statements unreachable by definition, therefore you don't need a return statement.

Note that while Halting problem is undecidable in generic case, the definition of Unreachable Statement is more strict than just halting. It's deciding very specific cases where a program definitely does not halt. The compiler is theoretically not able to detect all infinite loops and unreachable statements but it has to detect specific cases defined in the specification (for example, the while(true) case)


The compiler is smart enough to find out that your while loop is infinite.

So the compiler cannot think for you. It cannot guess why you wrote that code. Same stands for the return values of methods. Java won't complain if you don't do anything with method's return values.

So, to answer your question:

The compiler analyzes your code and after finding out that no execution path leads to falling off the end of the function it finishes with OK.

There may be legitimate reasons for an infinite loop. For example a lot of apps use an infinite main loop. Another example is a web server which may indefinitely wait for requests.


In type theory, there is something called the bottom type which is a subclass of every other type (!) and is used to indicate non-termination among other things. (Exceptions can count as a type of non-termination--you don't terminate via the normal path.)

So from a theoretical perspective, these statements that are non-terminating can be considered to return something of Bottom type, which is a subtype of int, so you do (kind of) get your return value after all from a type perspective. And it's perfectly okay that it doesn't make any sense that one type can be a subclass of everything else including int because you never actually return one.

In any case, via explicit type theory or not, compilers (compiler writers) recognize that asking for a return value after a non-terminating statement is silly: there is no possible case in which you could need that value. (It can be nice to have your compiler warn you when it knows something won't terminate but it looks like you want it to return something. But that's better left for style-checkers a la lint, since maybe you need the type signature that way for some other reason (e.g. subclassing) but you really want non-termination.)