【问题标题】:Are explicitly Infinite Loops handled in .NET as a special case?.NET 中是否明确处理无限循环作为特例?
【发布时间】:2011-11-11 12:09:30
【问题描述】:

今天早些时候,当我正在编写一个方法时,我突然意识到我并不确定我正在实现的习语为什么会编译。如果其他所有内容都被抽象出来,它会看起来像这样:

    private int Example()
    {
        while (true)
        {
            if (some condition)
            {
               return 1;
            }
        }
    }

您有一个明确的无限循环,以及循环内的一些条件,这些条件导致循环以 return 语句结束。让我们暂时忽略为什么我这样做,而不是检查 while 子句中的终止条件,因为答案令人费解且无关紧要——我想知道的是为什么编译器不会用“不”来标记它所有路径都返回一个值。”错误,严格来说,并非所有路径都返回一个值。从未进入 while 循环(当然,永远不会发生)的情况不会返回任何内容。

现在,我可以想象它发生的原因有两个:这是由于其他原因而发生的优化的副作用,或者这种情况正在由编译器明确处理以允许使用这种习惯用法。我的直觉是,这可能是第一个案例。例如,编译如下:

private int Example2()
{
   if (true) return 1;
}

因为编译器在 if 中看到了一个常量 true,并优化了条件。不过,我真的不明白为什么这会“修复”第一个示例。

哦,更奇怪的是,如果一些摆脱循环的优化正在发挥作用,它会编译:

    private int Example3()
    {
        while (true)
        {
            if (false)
            {
               return 1;
            }
        }
    }

我认为整个内部循环会被优化掉,去掉所有的有效返回。在字节码/编译器级别上到底发生了什么让这一切变得有意义?

【问题讨论】:

  • 我认为最后一个例子是编译器说“我希望他们知道他们在做什么......”
  • +1 从未想过这些情况。

标签: c# .net visual-studio bytecode compiler-optimization


【解决方案1】:

编译器不会对此进行标记,因为方法的结尾是无法访问。这不是问题 - 如果您可以在不返回值的情况下到达方法的末尾(右大括号),这只是一个问题。

这不是编译器的问题优化 - 这是遵循规范中规定的可达性定义的情况。

请注意,您根本不需要 return 语句...此代码无用,但完全有效:

public int EndlessLoop()
{
    while (true)
    {
    }
}

【讨论】:

【解决方案2】:

要为您提供此类无限循环的用例,请考虑以下代码:

public int KeyboardChecker()
{
    while (true)
    {
        if (KeyHasBeenPressed())
        {
            HandleKeyPress();
        }
    }
}

然后您在自己的线程上运行此方法,从而异步处理键盘输入(这是轮询模式,通常最好有一个事件系统)。

你可以想象线程完成后返回状态码,所以方法的返回值是 int。但是,由于这个特定的线程永远不会结束,所以该方法不包含任何 return 语句根本不是问题。 C# 设计者知道这些用例,并使得上述方法合法。

请注意,确定特定方法是否总是返回值的一般问题是无法确定的(即任何计算机程序都无法解决)。因此,C# 编译器可能会抱怨总是返回值的代码(尽管它永远不会接受不返回值的程序):

public int DoWork()
{
    // The compiler doesn't figure out this will always be true.
    if (((int)Math.Sqrt(4)) == 2)
    {
        return 3;
    }
    // And therefore complains that not all code paths return a value for this method.
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    相关资源
    最近更新 更多