【问题标题】:C# statement reachability and definite assignmentC# 语句可达性和明确赋值
【发布时间】:2013-05-11 18:26:12
【问题描述】:

我被 csc 对这段代码的反应难住了:

{
  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??
  }
}

在这段代码中,我有三个ifs 和一个未初始化的局部变量 i。 CSC 足够聪明,可以容忍我在第一种和第二种情况下使用 i,因为它可以告诉代码在哪里使用 i 是不可访问的。然而在第三种情况下,它抱怨 i“使用未分配的局部变量 i”的增量。为什么它在前两个 if 中正确检测到 i 在无法访问的代码中,但在第三个中没有(这只不过是前两种情况的组合?

【问题讨论】:

  • 这个问题真的不是关于明确的分配——而是关于可达性。
  • 你从哪里得到未初始化的? int 是一个值类型,所以它被初始化为零。
  • @TonyHopkinson i 是一个局部变量,这些不会为您自动初始化!至于我从哪里得到它,是编译器给了我这个错误!
  • 是的,所有值类型都在 .net 中初始化。阅读 CLR
  • @TonyHopkinson 我不知道如何将您的评论与这种情况联系起来,以下语句序列,在一个方法中,不编译: int kk;Console.WriteLine(kk);这不是 CLR 问题,而是 C# 问题

标签: c# variable-assignment


【解决方案1】:

C# 5 规范的第 8.7.1 节对此进行了解释:

如果if 语句可达且布尔表达式不具有常量值false,则if 语句的第一个嵌入语句是可达的。

尽管我们可以推断出这种情况:

false && i < 30

始终为false,根据语言规则(7.19),它不是常量表达式,因此正文中的第一个嵌入语句是可达的。

并不是所有涉及&amp;&amp; 的事情都是非假的。这很好,例如:

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

...但是因为表达式i &lt; 30 不是常量,所以您的原始表达式不是常量。 即使我们知道表达式永远不会被计算,情况也是如此。

语言可以决定 LHS 具有false 常量表达式的任何&amp;&amp; 表达式也是具有值false 的常量表达式,但事实并非如此。 (这只会增加少量的复杂性,但收益水平真的很小。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 2011-10-24
    • 1970-01-01
    • 2021-11-23
    • 2020-06-27
    • 1970-01-01
    • 2018-03-04
    相关资源
    最近更新 更多