代码之家  ›  专栏  ›  技术社区  ›  RobertFrank Picarus

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

  •  19
  • RobertFrank Picarus  · 技术社区  · 16 年前

    我正在将一些旧代码转换为Delphi2010。

    有相当数量的旧短字符串,如字符串[25]

    为什么下面的任务是:

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

    使编译器生成此警告:

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

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

    谢谢!

    托姆

    6 回复  |  直到 13 年前
        1
  •  14
  •   Nick Hodges    16 年前

    短字符串类型未更改。实际上,它仍然是一个ansichar数组。

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

        2
  •  16
  •   Mason Wheeler    16 年前

    因为你的代码是 含蓄地 将单字节字符串转换为单代码字符串。这是警告你,以防你可能忽视了它,因为如果你做的错误,可能会导致问题。

    要使其消失,请使用 明确的 转换:

    S := string(ShortS);
    
        3
  •  7
  •   Lars D    16 年前

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

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

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

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

        4
  •  1
  •   Steve    15 年前

    它是安全的(只要您使用短字符串的目的是:保存一个字符串而不是一组字节,其中一些可能是0),但如果您经常这样做,可能会影响性能。据我所知,Delphi必须为新的unicode字符串分配内存,将短字符串中的字符提取为以空结尾的字符串(这就是为什么它是一个格式正确的字符串很重要),然后调用类似于Windows API multiByteToWideChar()的函数。不是火箭科学,也不是一个微不足道的行动。

        5
  •  1
  •   Jens Mühlenhoff    13 年前

    短字符串没有与之相关联的代码页,ansistrings有(从d2009起)。

    从shortstring到unicodestring的转换只能在假定短字符串使用默认的ANSI编码(这不是一个安全的假设)的情况下进行。

        6
  •  -4
  •   Uri    16 年前

    我真的不知道delphi,但是如果我记得正确的话,短字符串本质上是堆栈上的一系列字符,而常规字符串(ansistring)实际上是对堆上某个位置的引用。这可能有不同的含义。

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

    我认为在编码方面也可能存在差异,但我不能百分之百确定。