【问题标题】:Str in XE7 generates strange warningXE7中的Str生成奇怪的警告
【发布时间】:2015-01-30 22:07:07
【问题描述】:

为什么会有这段代码:

  w: word;
  s: String;
begin
  str(w, s);

在 XE7 中生成此警告:

[dcc32 Warning] Unit1.pas(76): W1057 Implicit string cast from 'ShortString' to 'string'

汤姆

【问题讨论】:

  • 自从从 XE2 升级到 XE7 以来,我一直在处理的众多编译器警告之一。
  • 编译器实际上会生成一个对 _StrLong 的调用,该调用返回一个短字符串。这当然不是答案。
  • @Jerry - XE2 也是如此。
  • @Sertac 好吧,警告本身,而不是确切的情况。
  • @Jerry 完全一样。这里没有什么新鲜事

标签: string delphi delphi-xe7


【解决方案1】:

System.Str 是一个可以追溯到过去时代的内在函数。 documentation 是这样说的:

procedure Str(const X [: Width [:Decimals]]; var S: String);

....

注意:但是,在使用此过程时,编译器可能会发出警告:W1057 Implicit string cast from '%s' to '%s' (Delphi)。

如果不需要具有预定义最小长度的字符串,请尝试使用 IntToStr 函数。

由于这是内在的,因此可能会发生一些额外的事情。在幕后,内部函数是通过调用产生ShortString 的RTL 支持函数来实现的。编译器魔术然后将其转换为string。并警告您隐式转换。编译器魔法变换

Str(w, s);

进入

s := _Str0Long(w);

_Str0Long 在哪里:

function _Str0Long(val: Longint): _ShortStr;
begin
  Result := _StrLong(val, 0);
end;

由于_Str0Long 返回ShortString,因此编译器必须生成代码以在分配给变量s 时执行从ShortStringstring 的隐式转换。当然,您会自然而然地看到 W1057。

底线是 Str 的存在只是为了保持与旧版 Pascal ShortString 代码的兼容性。新代码不应调用Str。你应该按照文档说的做,然后打电话给IntToStr

s := IntToStr(w);

或许:

s := w.ToString;

【讨论】:

  • 将 System.Str 分配给 ShortString 是将整数转换为文本而不影响堆内存分配的一种方法。
  • @LURD 真实数据。我认为有更好的方法。无论如何,这里我们分配给string。但是对于那些性能至关重要的边缘情况,可以使用Str 来避免堆。
  • David:您在帖子中不包含“RTFM”,这让我非常克制。感谢您一贯的彻底回答。由于我们要迁移超过一百万行代码,因此我在第一阶段采用“尽可能少地更改”的路线,方法是在调用它的几行代码上使用 $WARNINGS OFF。 (它们实际上是 Str(w:3:1, S),所以还有比我提供的简单示例更多的内容......
  • @Tom 在短期内,全球禁用 W1057 不会造成伤害。从长远来看,您最终可能会得到w.ToString.PadLeft(3)
猜你喜欢
  • 2012-05-29
  • 2012-03-04
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
相关资源
最近更新 更多