【问题标题】:How to check that a method always returns a value如何检查一个方法是否总是返回一个值
【发布时间】:2015-01-01 20:57:09
【问题描述】:

我编写了一个已经可以正常工作的编译器。它检查所有非 void 方法是否至少有一个 return 语句,但它不检查非 void 方法中的所有代码路径是否都返回一个值。因此,例如,如果我有以下代码:

int function(bool a) 
{
     if(a){
         return 5;
     }
}

它将编译“正常”,如果 a 为 false,控制将放弃该函数并继续执行该函数下定义的任何内容。

是否有一些算法可以用来执行此检查,以便我始终知道某个方法是否始终返回一个值?还是我需要重新发明轮子?

【问题讨论】:

标签: compiler-construction compilation


【解决方案1】:

无论函数是否返回值,函数都不能“落到尽头”并开始执行超出其范围的代码。对于不返回结果的函数(或者在一些无纪律的语言中,即使对于确实返回结果的函数),允许省略最后的 return 语句是很常见的,但函数在所有情况下都需要返回。

鉴于此,为最终落下的非 void 函数生成错误消息的最简单方法是:

  • 解析器在函数体末尾插入return语句。

  • 死代码消除用于删除插入的return语句,以防不必要。

  • 类型检查用于验证所有return 语句,包括插入的未删除的语句,是否与函数的返回类型一致。 (即由于生成的return语句没有值,只能与void函数一致。)

在这种情况下,您需要在类型检查之前删除不必要的return 语句,否则您最终会收到很多不正确的错误消息。这需要一些控制流分析。

如果工作量太大,您可以在运行时通过将无值return 语句编译为函数返回值的错误操作来发出错误消息。

【讨论】:

  • 虽然这确实解决了“落到尽头”的问题,但我认为这不是问题所在。据我了解,问题是如果不是所有路径都返回值,如何产生编译时错误。
  • 对于不返回值的函数,我会按照您的建议进行操作。但不能对那些这样做的人做同样的事情,因为我不能简单地猜测返回值是什么。很明显,功能从头到尾不应该发生。我要问的是如何检测这种情况,以便编译器报告错误并停止编译。
  • @sepp2k 正是我的意思。
  • 最终问题已按照@rici 建议的方式修复。
  • @sepp2k:我编辑了答案以更清楚地表明我试图回答原始问题。虽然我觉得和之前的回答没什么区别,除了一些化妆品。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
  • 1970-01-01
相关资源
最近更新 更多