Почему Delphi предупреждает при назначении ShortString в строку? - PullRequest
19 голосов
/ 23 января 2010

Я конвертирую какой-то устаревший код в Delphi 2010.

Существует довольно много старых ShortStrings, например string [25]

Почему задание ниже:

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

...
S := ShortS;

заставляет компилятор генерировать это предупреждение:

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

Здесь не происходит потеря данных. При каких обстоятельствах это предупреждение будет для меня полезной информацией?

Спасибо!

Tomw

Ответы [ 6 ]

16 голосов
/ 23 января 2010

Это потому, что ваш код неявно преобразует однобайтовую символьную строку в UnicodeString. Он предупреждает вас на случай, если вы пропустили это, поскольку это может вызвать проблемы, если вы сделаете это по ошибке.

Чтобы все прошло, используйте явное преобразование:

S := string(ShortS);
14 голосов
/ 23 января 2010

Тип ShortString не изменился. По сути, он остается массивом AnsiChar.

Присвоив его строковому типу, вы берете группу AnsiChars (один байт) и помещаете ее в группу WideChars (два байта). Компилятор может сделать это просто замечательно и достаточно умен, чтобы не потерять данные, но есть предупреждение, чтобы сообщить, что такое преобразование имело место.

7 голосов
/ 23 января 2010

Предупреждение очень важно, потому что вы можете потерять данные. Преобразование выполняется с использованием текущего 8-разрядного набора символов Windows, и некоторые наборы символов не определяют все значения от 0 до 255 или являются многобайтовыми наборами символов и, следовательно, не могут преобразовать все значения байтов.

Потеря данных может происходить на стандартном компьютере в стране с определенными стандартными наборами символов или на компьютере в США, который был настроен для другой локали, поскольку пользователь много общается с людьми на других языках.

Например, если локальная кодовая страница равна 932, байтовые значения 129 и 130 будут преобразованы в одно и то же значение в строке Unicode.

В дополнение к этому преобразование включает вызов Windows API, который является дорогостоящей операцией. Если вы делаете много из них, это может замедлить ваше приложение.

1 голос
/ 20 февраля 2013

ShortStrings не имеют связанной с ними кодовой страницы, как AnsiStrings (начиная с D2009).

Преобразование из ShortString в UnicodeString может быть сделано только в предположении, что ShortStrings закодированы в кодировке ANSI по умолчанию, которая не является безопасным допущением.

1 голос
/ 14 октября 2010

Это безопасно (если вы используете ShortString по прямому назначению: хранить строку символов, а не набор байтов, некоторые из которых могут быть 0), но может иметь последствия для производительности, если вы это сделаете много. Насколько я знаю, Delphi должен выделить память для новой строки Unicode, извлечь символы из ShortString в строку с нулевым символом в конце (поэтому важно, чтобы это была правильно сформированная строка), а затем вызвать что-то вроде Windows API Функция MultiByteToWideChar (). Не ракетостроение, но и не тривиальная операция.

0 голосов
/ 23 января 2010

Я действительно не знаю Delphi, но если я правильно помню, строки коротких строк - это, по сути, последовательность символов в стеке, тогда как обычная строка (AnsiString) на самом деле является ссылкой на местоположение в куче. Это может иметь разные последствия.

Вот хорошая статья о различных типах строк: http://www.codexterity.com/delphistrings.htm

Я думаю, что также может быть разница в кодировании, но я не уверен на 100%.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...