XE7 中的 Str 生成奇怪的警告

Str in XE7 generates strange warning

为什么这个代码:

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

在 XE7 中生成此警告:

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

汤姆

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

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

....

Notes: However, on using this procedure, the compiler may issue a warning: W1057 Implicit string cast from '%s' to '%s' (Delphi).

If a string with a predefined minimum length is not needed, try using the IntToStr function instead.

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

Str(w, s);

进入

s := _Str0Long(w);

其中 _Str0Long 是:

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

因为 _Str0Long returns a ShortString 那么编译器必须生成代码来执行从 ShortStringstring 的隐式转换,当它分配给你的变量 s。当然,您很自然地会看到 W1057。

底线是 Str 的存在只是为了保持与遗留 Pascal ShortString 代码的兼容性。新代码不应调用 Str。您应该按照文档中的说明进行操作并调用 IntToStr:

s := IntToStr(w);

或者也许:

s := w.ToString;