Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# statement reachability and definite assignment

I am stumped by the reaction from csc to this code:

{
  int i;
  if (false)
  {
    i++;                // uninitialized, but allowed by compiler
  }
  if (false && i < 30)  // uninitialized, but allowed by compiler
  {
  }
  if (false && i < 30)  // uninitialized, but allowed by compiler
  {
    i++;                // NOT ALLOWED by compiler??
  }
}

In this code I've got three ifs and one uninitialized local variable i. CSC is smart enough to tolerate my use of i in the first and second cases since it can tell the code where i is being used is unreachable. Yet on the third case, it complains on the increment of i "use of unassigned local variable i". Why is it correctly detecting i is in unreachable code in the first two ifs, but not in the third (which is nothing but a combination of the first two cases?

like image 600
Mishax Avatar asked Mar 24 '23 00:03

Mishax


1 Answers

This is explained by section 8.7.1 of the C# 5 specification:

The first embedded statement of an if statement is reachable if the if statement is reachable and the boolean expression does not have the constant value false.

Even though we can reason that this condition:

false && i < 30

is always false, it's not a constant expression according to the rules of the language (7.19), so the first embedded statement in the body is reachable.

It's not that everything involving && is non-false. This is fine, for example:

if (false && true)
{
    i++;
}

... but because the expression i < 30 isn't constant, your original expression isn't constant. This is the case even though we know that expression would never be evaluated.

The language could decide that any && expression where the LHS had a constant expression of false was also a constant expression with the value false, but it doesn't. (It would only be a small amount of added complexity, but the level of benefit is really small.)

like image 181
Jon Skeet Avatar answered Apr 06 '23 18:04

Jon Skeet