2010-01-22 40 views
17

我把一些旧代码至2010年德尔福为什么在将ShortString分配给字符串时,Delphi会发出警告?

有相当数量的老ShortStrings,像串[25]

为什么如下分配:

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

... 
S := ShortS; 

原因编译器生成此警告:

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

这里没有数据丢失。这种警告在什么情况下对我有帮助?

谢谢!

Tomw

回答

14

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

通过将它分配给一个字符串类型,您正在将什么是一组AnsiChars(一个字节)并将其放入一组WideChars(两个字节)中。编译器可以做到这一点,并且足够聪明,不会丢失数据,但警告会告诉您这种转换已经发生。

+2

谢谢,尼克。既然它很安全,我只是觉得警告是多余的。 无论如何,恭喜D2010。目前我正在享受转型。你们提供的白皮书(特别是卡里的)非常有帮助。 – RobertFrank 2010-01-23 00:06:37

+2

请考虑删除“足够聪明,不会丢失数据”。这是不可能发生的,除了所有的编译器“聪明”之外。 – mghie 2010-01-23 06:06:25

+4

这个CAN会让你丢失数据,只是因为并非所有代码页中定义的短字符串中0-255的值都是明确的。 – 2010-01-23 09:08:30

13

这是因为你的代码是隐含转换单字节字符字符串到的UnicodeString。如果您可能忽略了它,它会警告您,因为如果您错误地执行操作,可能会导致问题。

要让它消失,使用明确转换:

S := string(ShortS); 
-3

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

这里有不同的字符串类型的好文章: http://www.codexterity.com/delphistrings.htm

我觉得也可能是在编码方面有差别,但我不是100%肯定。

+0

@Uri:自Delphi 2009以来,string是WideString而不是AnsiString。警告没有任何关于哪个内存结构/位置是分配的变量。 – jachguate 2010-01-23 00:28:02

+1

@jachguate:谢谢。无可否认,自从21世纪初以来,我一直没有碰到德尔福。 – Uri 2010-01-23 05:10:05

6

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

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

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

除此之外,转换涉及Windows API调用,这是一项昂贵的操作。如果你做了很多这些,它会减慢你的应用程序。

+1

你可以在这里获得更多信息:http://docs.google.com/gview?url=http://embarcadero.com/images/dm/technical-papers/delphi-unicode-migration.pdf&pli=1 – 2010-01-23 09:27:58

+0

我'对不起,但该代码页中的字节值129和130是DBCS引导字节,并且仅与尾部字节一起具有含义。查看http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT。恕我直言,如果源字符串包含无效的DBCS序列,说错失数据。之前已经失去了。 – mghie 2010-01-23 10:08:58

+0

例如,通过在不同的代码页中加载字符数据,而没有进行正确的转换。 – mghie 2010-01-23 10:15:21

1

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

1

ShortStrings没有与它们相关的代码页,AnsiStrings(自D2009以来)。

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

相关问题