代码之家  ›  专栏  ›  技术社区  ›  Benny

为什么在这种情况下编译器不抱怨?

  •  3
  • Benny  · 技术社区  · 15 年前

    这是代码:

     private TreeNode GetTopLevelNode(TreeNode childNode)
        {
            if (childNode == null)
                throw new ArgumentNullException("childNode", "childNode is null.");
    
            if (childNode.Parent == null) return childNode;
    
            TreeNode node = childNode;
            while (true)
            {
                if (node.Parent == null)
                {
                    return node;
                }
                node = node.Parent;
            }
    
        }
    

    在while循环中,只有当node.parent==null时,才会返回一个节点,

    为什么编译器不报告“并非所有代码路径都返回值”错误?

    如果不能满足“node.parent==null”,则不会返回树节点。 编译器无法检测到这种情况?

    5 回复  |  直到 15 年前
        1
  •  10
  •   zmbush    15 年前

    因为你在使用 while(true){ ,只有使用返回才能退出循环。如果 node.parent == null 如果不能满足,那么它将是一个无限循环。因此,没有办法不返回就通过循环,编译器也不会抱怨。

    另外,您指定的代码几乎总是返回一个空值 TreeNode ,这是你真正想要的吗?

    编辑:我看到你修好了。

        2
  •  9
  •   Eric Lippert    15 年前

    你的问题实际上是计算机科学中最深刻最有趣的问题之一。这个问题被称为暂停问题:给定一个程序的问题,决定它是否总是返回或永远运行。

    停顿问题是著名的,因为它是可以证明的。 计算机无法解决 .没有一种算法能够可靠地告诉您给定的程序是否停止。你可以证明这样一个程序要么(1)给出错误的答案,(2)不能分析所有程序,要么(3)它本身有时从不停止。

    因此,C编译器不会试图解决暂停问题。相反,我们只是检测到“while(true)”和缺少中断意味着循环永远不会“离开底部”,因此方法的终点是不可到达的。实际上,错误“并非所有代码路径都返回值”是什么? 方法 是否“存在退出方法但不返回值的代码路径”。它确实 意思是“有一条永远运行的代码路径”——因为计算出来需要解决暂停问题。

        3
  •  1
  •   Jeremy McGee    15 年前

    编译器很聪明,可以优化循环。它知道唯一的出路是在 if (node.Parent == null) 条件返回 true .

        4
  •  1
  •   Adriaan Stander    15 年前

    除非你有 无限深度 或者 这段时间将永远持续下去。

    所以要么循环被卡住,要么在某个时刻父循环将为空。它永远不会进入,因为它不会结束。

        5
  •  1
  •   sth Alien    15 年前

    编译器意识到函数将返回 TreeNode 在所有情况下,它都将终止。在函数返回的所有情况下,它都将返回正确的值。因此,在任何情况下都不会返回未定义的值,并且编译器没有看到警告的原因。

    如果函数不返回,则不需要考虑返回值。