为什么这个明显的无限递归没有给出编译器警告?

jos*_*urs 8 c# c++ python compiler-construction recursion

几个月前,我不得不修复一些导致一些问题的代码.代码看起来基本上是这样的:

int badFun() { return badFun(); }

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

编辑:我尝试在所有三种语言中编写相应的函数,所以我添加了这些函数标签.我对代码这样的代码没有任何警告的整体原因更感兴趣.如有必要,请重新登记.

Eri*_*ert 38

这是交易:编译器警告是功能.功能需要努力,而努力是有限的数量.(它可以用美元来衡量,也可以用某人愿意给开源项目的小时数来衡量,但我保证,它是有限的.)

因此,我们必须预算这项工作.我们花费在设计,实现,测试和调试功能上的每一个小时都是我们可以用来做其他事情的一小时.因此,我们非常谨慎地决定要添加哪些功能.

所有功能都是如此.警告还有其他特殊问题.警告必须是关于具有以下特征的代码:

  • 法律.显然,代码必须是合法的; 如果它不合法,那么它首先不是警告,它是一个错误.
  • 几乎肯定是错的.警告警告您正确,理想的代码是一个坏警告.(另外,如果代码正确的,应该有一种方法来编写代码,使警告消失.)
  • Inobvious.警告应该告诉你哪些错误是微妙的,而不是明显的.
  • 适合分析.有些警告根本不可能; 例如,需要编译器解决停止问题的警告不会发生,因为这是不可能的.
  • 不太可能被其他形式的测试所捕获.

在您的具体示例中,我们看到满足其中一些条件.代码是合法的,几乎肯定是错的.但它不明显吗?有人可以轻松查看代码并看到它是无限递归; 警告没有多大帮助.是否适合分析?你给出的简单例子是,但找到无界递归的一般问题等同于解决暂停问题.是否不太可能被其他形式的测试所捕获?不.在您的测试用例中运行该代码的那一刻,您将得到一个例外,告诉您确切的错误.

因此,发出警告是不值得的.我们有更好的方式来支出这个预算.

  • +1优秀的答案,真正得到我所询问的.我知道编译器不应该让你不要编写糟糕的代码,但好的编译器至少应该抛出一个"嘿,那里有什么?" 有时. (2认同)
  • 有一个相关的问题是`int BadProperty {get {return BadProperty;}}`和它的setter等价物,这个错误非常容易制作,而且不容易发现.但是,当您实际运行代码时,这个问题显然很容易被发现,这大大降低了此功能的优势. (2认同)
  • @CodeInChaos:的确,这是警告可能合理的地方. (2认同)

Cal*_*leb 20

为什么默认情况下这不是问题?

错误是运行时错误,而不是编译时错误.代码完全有效,它只是做一些愚蠢的事情.您显示的非常简单的情况当然可以被检测到,但许多只会稍微复杂的情况很难检测到:

void evil() {
    if (somethingThatTurnsOutToAlwaysBeTrue)
        evil();
}
Run Code Online (Sandbox Code Playgroud)

为了确定这是否是一个问题,编译器必须试图弄清楚条件是否总是为真.在一般情况下,我认为这比计算程序最终是否会停止(即可证明是不可计算的)更具可计算.

  • +1.编译器不打扰,因为暂停问题在一般情况下是不可计算的. (17认同)