为什么这个明显的无限递归不给编译器一个警告?

2024-10-01 04:56:18 发布

您现在位置:Python中文网/ 问答频道 /正文

几个月前,我不得不修改一些导致一些问题的代码。代码基本上是这样的:

int badFun() { return badFun(); }

这显然导致了堆栈溢出,即使是在我使用的高级语言中(SilkTest中的4Test)。这段代码不可能被视为有益的。问题的第一个迹象是脚本完成后出现警告,但没有出现编译错误或警告。奇怪的是,我尝试用相同的结构编写C++程序、C语言和Python程序,并且所有这些程序都编译或解释,没有语法错误或警告,即使在所有情况下都有运行时错误。我甚至没有看到任何警告。为什么这在默认情况下不被视为可能的问题?在

编辑:我尝试用所有三种语言编写这个函数的等价物,所以我添加了这些函数标记。我更感兴趣的是为什么这样的代码可以在没有警告的情况下通过。如有必要,请重新打电话。在


Tags: 函数代码程序脚本语言警告return堆栈
3条回答

任何编程语言的编译器都不知道它所编译的代码的语义。这是一个有效的代码,虽然很愚蠢,所以它将被编译。在

这里有个交易:编译器警告是特性。特征需要付出有限的努力。(它可以用美元来衡量,也可以用人们愿意为开源项目付出的时间来衡量,但我向你保证,这是有限的。)

因此,我们必须对这一努力进行预算。我们花在设计、实现、测试和调试一个特性上的每一个小时都是我们可以用来做其他事情的一个小时。因此,我们非常谨慎地决定要添加哪些特性。在

所有功能都是这样。警告还特别值得关注。警告必须与具有以下特征的代码有关:

  • 合法的。显然,代码必须是合法的;如果它不合法,那么首先它不是警告,而是一个错误。在
  • 几乎肯定是错的。警告您正确的、需要的代码的警告是错误的警告。(此外,如果代码正确,则应该有一种方法来编写代码,以使警告消失。)
  • 无偏见。警告应该告诉你一些细微的错误,而不是显而易见的错误。在
  • 易于分析。有些警告根本是不可能的;例如,需要编译器解决停止问题的警告不会发生,因为这是不可能的。在
  • 不太可能被其他形式的测试抓住。在

在您的具体例子中,我们看到其中一些条件得到满足。这一准则是合法的,而且几乎肯定是错误的。但它是不是无关紧要?有人可以很容易地看到代码,并看到它是一个无限递归;警告没有多大帮助。它是否适合分析?你给出的一个简单的例子是,但是寻找无界递归的一般问题等同于解决停顿问题。它不太可能被其他形式的测试抓住吗?不,当你在你的测试用例中运行代码的时候,你会得到一个异常,告诉你到底出了什么问题。在

因此,我们不值得作出这种警告。我们可以用更好的方法来花这笔预算。在

Why isn't this seen as problem by default?

该错误是运行时错误,而不是编译时错误。代码完全有效,只是做了些蠢事。您所展示的非常简单的案例当然可以被检测到,但许多情况只会稍微复杂一点就很难检测到:

void evil() {
    if (somethingThatTurnsOutToAlwaysBeTrue)
        evil();
}

为了确定这是否是一个问题,编译器必须找出条件是否总是为真。在一般情况下,我不认为这比确定程序是否最终停止(即它是provably not computable)更具可计算性。在

相关问题 更多 >