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

时间:2010-01-22 23:28:26

标签: delphi

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

有很多旧的ShortStrings,比如string [25]

为什么下面的作业:

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

...
S := ShortS;

导致编译器生成此警告:

W1057 Implicit string cast from 'ShortString' to 'string'.

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

谢谢!

Tomw

6 个答案:

答案 0 :(得分:16)

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

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

S := string(ShortS);

答案 1 :(得分:14)

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

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

答案 2 :(得分:7)

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

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

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

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

答案 3 :(得分:1)

它是安全的(只要你将ShortString用于其预期目的:保存一串字符而不是字节集合,其中一些可能是0),但是如果你这样做可能会对性能产生影响很多。据我所知,Delphi必须为新的unicode字符串分配内存,将ShortString中的字符提取为以null结尾的字符串(这就是为什么它是一个正确形成的字符串很重要),然后调用类似Windows API的内容MultiByteToWideChar()函数。不是火箭科学,也不是一项微不足道的操作。

答案 4 :(得分:1)

ShortStrings没有与之关联的代码页,AnsiStrings就是这样(自D2009以来)。

从ShortString到UnicodeString的转换只能在假设ShortStrings以默认的ANSI编码进行编码的情况下完成,这不是一个安全的假设。

答案 5 :(得分:-4)

我真的不知道Delphi,但如果我没记错的话,Shortstrings本质上是堆栈中的一系列字符,而常规字符串(AnsiString)实际上是对堆上位置的引用。这可能有不同的含义。

这是一篇关于不同字符串类型的好文章: http://www.codexterity.com/delphistrings.htm

我认为在编码方面也可能存在差异,但我并不是100%肯定。