m.edmondson
m.edmondson

Reputation: 30872

Not all code paths return a value - but they do

The following extract of code is failing to compile resulting in not code paths return a value. Both types Test1StandardChargeCalculator and Test2StandardChargeCalculator are derived from the return type.

I know how to fix this, but my question is why should I have to? A bool is a value type - hence can only represent true or false, both of which are catered for in this snippet. So why the failed compilation?

internal StandardChargeCalculator Create()
{
      bool value = true;

      switch (value)
      {
          case true:
              return new Test1StandardChargeCalculator();
          case false:
              return new Test2StandardChargeCalculator();
      }
} //not all code paths return a value

Upvotes: 4

Views: 1283

Answers (5)

Henk Holterman
Henk Holterman

Reputation: 273209

In Absence of evidence is not evidence of absence Eric Lippert writes about the limitations of 'proofing' that a variable is unassigned and the weaker aim of the compiler in this regard:

that we're not interested in proving for certain that x is unassigned. We're interested in proving for certain that x is assigned! If we can prove that for certain, then x is "definitely assigned". If we cannot prove that for certain then x is "not definitely assigned".

Which does not directly explain this example but note that it is the same issue as :

int x;

if (a < 10) 
   x = 0;
else if (a >= 10)
   x = 1;

y = x; // x is 'unassigned'

We can quickly see that x will always be assigned, the compiler does not even attempt to find out.

Upvotes: 4

benJima
benJima

Reputation: 131

To my understanding it is inconsistant to the definition of the switch which says:

If no case expression matches the switch value, then control is transferred to the statement(s) that follow the optional default label. If there is no default label, control is transferred outside the switch.

You are right: there should be no compiler error. So, this might be a case where no answer is the answer. You will have to live with it.

    switch (answer)
    {
    ...
    default:
    return "It is as it is"
    }

Upvotes: 0

JleruOHeP
JleruOHeP

Reputation: 10376

Maybe better solution would be

internal StandardChargeCalculator Create()
{
  StandardChargeCalculator result = null;
  bool value = true;

  switch (value)
  {
    case true:
      result = new Test1StandardChargeCalculator();
      break;
    case false:
      result = new Test2StandardChargeCalculator();
      break;
  }
  return result;
}

Upvotes: -3

to StackOverflow
to StackOverflow

Reputation: 124696

Why do you think the compiler should special-case boolean and detect that all possible values have a case statement?

If you were writing a compiler, would you invest development effort and increase the risk of bugs by implementing this?

Upvotes: 4

Oded
Oded

Reputation: 498972

When using a switch statement, the compiler does not understand that when you are using a boolean type to switch on there can only be two results.

The error occurs because you do not have a default case.

Don't use a switch for boolean test - use an if statement:

  bool value = true;

  if(value)
  {
      return new Test1StandardChargeCalculator();
  }

  return new Test2StandardChargeCalculator();

Upvotes: 15

Related Questions