Delphi编译器没有对此代码发出警告

8

在调试我的代码时,我注意到Delphi编译器(Berlin 10.1)不会警告没有返回值的函数。这是正常的吗?

以下是一个简单的示例:

function f(s:string):String;
begin
  stringreplace(s,#32,'',[rfReplaceAll]);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   showmessage(F('te st'));
end;

这一行

 stringreplace(s,#32,'',[rfReplaceAll]);

应该是

result:= stringreplace(s,#32,'',[rfReplaceAll]);

没有警告!

我认为它应该警告“返回值可能未定义”。但它没有。 在过去的几天里,我更改并重写了一些旧代码的部分。我担心我的应用程序中存在这种错误。


@user202729,我没有关闭任何警告。同时,我得到了返回值可能未定义的其他情况。 - Shahram Banazadeh
2
有一些静态代码分析工具可以帮助识别这种类型的错误,参见有没有适用于Delphi/Pascal的静态代码分析工具? - LU RD
@LURD 尝试过这个。它有一些好的功能和一些错误(例如在分析中包括注释部分的代码,未使用的循环变量和错误检测到短路if语句),但它也不识别这些错误。谢谢。 - Shahram Banazadeh
是 FixInsight 吗?正如 @DavidHeffernan 在他的回答中提到的那样? - LU RD
1
@LURD Fixinsight 发现了它! - Shahram Banazadeh
显示剩余2条评论
1个回答

9
这是一个编译器缺陷。管理类型返回值被实现为var参数。因此,一旦编译器将函数转换为具有额外var参数的过程以返回值,它会看到一个var参数,它假定是由调用者初始化的。这就是问题的根本原因。虽然我不是在为其辩护,但它是一个明显的缺陷,而且是一个糟糕的缺陷。我只是提供了一些背景知识,说明它是如何发生的。
在此情况下,你无法做很多事情。也许最好的方法是确保你的代码具有强大的单元测试覆盖率。类似FixInsight的静态分析工具也可以用来帮助你发现代码中的错误。

我使用 Delphi Berlin 10.1。(我编辑了我的帖子以添加此细节)然后我认为我必须再次阅读我的更改代码。而且当我很困的时候不要编码,绝对不行!谢谢您的回答。 - Shahram Banazadeh
1
@David:不,即使是Tokyo 10.2.2,如果结果类型是托管的,也不会发出警告。尝试使用dynarrays和strings:没有警告。整数或双精度浮点数:警告。因此,没有任何改变。 - Rudy Velthuis
1
FWIW:https://quality.embarcadero.com/browse/RSP-16880 - 至于行为本身,我认为Allen Bauer曾经提到警告是在生成参数列表之后的阶段生成的,因此不知道这个var参数实际上是函数结果,使得修复变得相当复杂。 - Stefan Glienke
1
@Stefan:我认为未分配结果检查是在后期进行的,而不仅仅是生成警告。但如果他们真的关心的话,他们可以携带一个指示某个参数应该是结果并检查它的标志。 - Rudy Velthuis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接