为什么Delphi会在将ShortString分配给字符串时发出警告?

Rob*_*ank 20 delphi

我正在将一些遗留代码转换为Delphi 2010.

有很多旧的ShortStrings,比如字符串[25]

为什么下面的作业:

type 
  S: String;
  ShortS: String[25];

...
S := ShortS;
Run Code Online (Sandbox Code Playgroud)

导致编译器生成此警告:

W1057 Implicit string cast from 'ShortString' to 'string'.
Run Code Online (Sandbox Code Playgroud)

这里没有数据丢失.在什么情况下这个警告对我有用?

谢谢!

Tomw

Mas*_*ler 18

这是因为您的代码隐式地将单字节字符串转换为UnicodeString.如果您可能忽略了它,它会警告您,因为如果您误操作可能会导致问题.

要使其消失,请使用显式转换:

S := string(ShortS);
Run Code Online (Sandbox Code Playgroud)


Nic*_*ges 15

ShortString类型没有改变.实际上,它仍然是一系列的AnsiChar.

通过将其分配给字符串类型,您将获取一组AnsiChars(一个字节)并将其放入一组WideChars(两个字节).编译器可以很好地做到这一点,并且足够聪明,不会丢失数据,但警告会告诉您已经发生了这样的转换.

  • 这会导致您丢失数据,因为并非所有代码页中都定义了短字符串中0-255的所有值. (4认同)
  • @Nick:这是一个丢失数据的例子:Code,使用blockread直接从文件中读取utf-8到shorttring中,将文本保存在tstringlist中,然后将它从tstringlist中拉出到shorttring或ansistring中.这在Delphi 2007中完美运行,但在Delphi 2009中,该代码会丢失/损坏具有某些代码页的PC上的数据(如CP 932).在字符串赋值的shorttring期间会发生损坏/数据丢失. (3认同)
  • 谢谢,尼克.既然它是安全的,我只是认为警告是多余的.无论如何,恭喜D2010.到目前为止,我很享受这种转变.你们提供的白皮书(特别是卡里的)非常有帮助. (2认同)
  • 请考虑删除"足够智能,不会丢失数据".没有办法可以*永远*发生,所有编译器"智能"放在一边. (2认同)
  • @mghie:这是一个危险且常常不正确的假设.我的大多数短串都是旧的加密,压缩模块和分析二进制数据的模块,而shorttring-to-unicodestring赋值是我们在升级这些模块时必须删除的事情之一,以防止数据丢失. (2认同)

Lar*_*s D 7

警告非常重要,因为您可能会丢失数据.使用当前的Windows 8位字符集完成转换,并且某些字符集不定义0到255之间的所有值,或者是多字节字符集,因此无法转换所有字节值.

数据丢失可能发生在具有特定标准字符集的国家/地区的标准计算机上,或者发生在美国已设置为不同语言环境的计算机上,因为用户与其他语言的人员进行了大量通信.

例如,如果本地代码页是932,则字节值129和130都将转换为Unicode字符串中的相同值.

除此之外,转换涉及Windows API调用,这是一项昂贵的操作.如果你做了很多这样的事情,它可能会减慢你的申请速度.

  • @mghie:数据丢失的一个很好的例子是一些代码,它使用blockread直接从文件中读取utf-8到shorttring中,将数据保存在tstringlist中,然后将它从tstringlist中拉出到shorttring中.这在Delphi 2007中完美运行,但在Delphi 2009中,该代码会丢失/损坏某些PC上的数据. (2认同)