Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle "not all code paths return a value" when the logic of the function does ensure a return

I suppose the easiest way to explain is by a contrived example:

public static int Fail() {
    var b = true;
    if (b) {
        return 0;
    }
}

This code will not compile, and gives the error "not all code paths return a value," while we humans can clearly see that it does. I DO understand why. My question is what should be done to remedy the situation. It could be something like this:

public static int Fail() {
    var b = true;
    if (b) {
        return 0;
    }
    throw new ApplicationException("This code is unreachable... but here we are.");
}

But it all just seems rather silly. Is there a better way? Again, this code is a contrived example (and can be reduced to return 0). My actual code is massive and complex, but does logically (by mathematical proof) return a value before trying to exit.

like image 279
Brent Avatar asked Aug 24 '13 22:08

Brent


3 Answers

C# code flow analysis is limited and as your sample points out there are cases where all paths do return but the compiler can't detect it. Throwing an exception is an acceptable remedy in those circumstances.

I would not use a return of a default value to fix this error. You're operating under the assumption that the line is never hit against the advice of the compiler. Consider for a second that your analysis is wrong and execution can proceed to the end of the method. If you return a default value then you will have no indication of the problem. The method will just be returning bad data. Throwing an exception will make it very obvious that there is a problem.

However in those cases my preference is to simply rewrite the code such that the compiler can see that all paths terminate. In general I've found that if the method is so complex that the compiler can't follow it then the guy who picks up the code after me won't be able o follow it either.

like image 77
JaredPar Avatar answered Sep 28 '22 18:09

JaredPar


I think your current approach is correct. Returning a default value at the end of the method is risky, because if there's a flow in your logic, this instruction could be reached, which could have unintended consequences. If you throw an exception, it gives you a chance to detect the mistake.

like image 32
Thomas Levesque Avatar answered Sep 28 '22 18:09

Thomas Levesque


The compiler doesn't perform complex mathematical processes to ensure you return a value, it's a relatively dumb beast in that regard.

If you're certain of your assumptions, just add return 0; at the end with a comment stating the reality, that it will never be reached.

Of course, any code where it can be guaranteed the final condition will be true can just have the condition removed, as you've already stated. That's mathematically true even for complex cases. So you could refactor your code to take that into account without a superfluous return.

like image 21
paxdiablo Avatar answered Sep 28 '22 16:09

paxdiablo