Подтвердить что ты не робот

Почему Delphi предупреждает при назначении ShortString строке?

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

Существует множество старых ShortStrings, таких как строка [25]

Почему следующее назначение:

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

...
S := ShortS;

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

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

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

Спасибо!

Tomw

4b9b3361

Ответ 1

Тип ShortString не изменился. Он по-прежнему остается массивом AnsiChar.

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

Ответ 2

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

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

S := string(ShortS);

Ответ 3

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

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

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

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

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

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