FPC 3.0 RC1 announced

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

sts
энтузиаст
Сообщения: 519
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

Mikhail писал(а):Это не совсем так...


ага на второй круг пошли, ну расскажите что конкретно не совсем так?
Mikhail
энтузиаст
Сообщения: 565
Зарегистрирован: 24.10.2013 16:06:47

Сообщение Mikhail »

sts писал(а):
Mikhail писал(а):Это не совсем так...


ага на второй круг пошли, ну расскажите что конкретно не совсем так?

Ну вот например,

Код: Выделить всё

ttt = record
 name:string;
 ...
end;


переменные такого типа легко писались в файл в TP7

Это к вопросу о том, нужно ли знать как оно устроено и работает.
sts
энтузиаст
Сообщения: 519
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

Mikhail писал(а):переменные такого типа легко писались в файл в TP7

Это к вопросу о том, нужно ли знать как оно устроено и работает.


и? что поменялось?
kazalex
постоялец
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Сообщение kazalex »

Mikhail писал(а):Вот и я о том же. Поэтому мне не понятно зачем нужны строки с кодировкой.

Приложение работающее с юникод-строками (будем считать таковыми строки в кодировке utf-16, как оно сделано в дельфях и много где ещё), получая данные извне, должно привести их в соответствие со своим внутренним форматом. Для этого перекодирование и требуется, а уж как оно будет выполнено, с использованием таких строк или с помощью специальных классов зависит от. Можно краткий пример. Например, мы читаем ответ от http-сервера из сокета. Рассмотрим чтение заголовков. Для чтения из сокета нам нужен буфер, который потом придётся конвертировать в юникод-строку т.к. внутри у нас всё юникодное, а данные приходят в однобайтовой латинице. Самое простое, это взять строку LatinString (AnsiString(8859), вроде) и использовать её в качестве буфера для получения данных. Дальнейшее конвертирование в юникод-строку будет осуществлено простейшим присваиванием. Также, может оказаться удобным хранение http-заголовоков в виде массива строк LatinString т.к. это вдвое снижает нагрузку на память, а публичный итерфейс класса будет отдавать их в виде юникод-строк используя всё то же элементарное преобразование присваиванием.
Mikhail писал(а):Имеет, но сейчас разговор не об этом.

Не имеет, хоть сейчас и не об этом :)
Mikhail писал(а):А информация о типе (т.е. кодировка) находится в скрытом блоке перед строкой, как в Делфи, я правильно понимаю?

Информация о типе известна компилятору на момент компиляции.

Код: Выделить всё

type DosString = type AnsiString(866);

Информация о кодировке содержится в служебном заголовке строки вместе с информацией о размере элемента строки.

p.s. Я не могу сказать, что без строк с информацией о кодировке невозможно жить, но с ними всё же лучше.
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

kazalex писал(а):Самое простое, это взять строку LatinString (AnsiString(8859), вроде) и использовать её в качестве буфера для получения данных. Дальнейшее конвертирование в юникод-строку будет осуществлено простейшим присваиванием.


При чтении кода, по таким присваиваниям не видно, что они идут с конвертированием. И это плохо, т.к. может быть важно.
kazalex
постоялец
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Сообщение kazalex »

Mirage, читать тут, последний абзац.
Аватара пользователя
hinst
энтузиаст
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Сообщение hinst »

Фича говно хотя бы потому, что она ломает обратную совместимость. Раньше string это был AnsiString а теперь string это не AnsiString

Я вижу FPC пошёл по стопам Delphi, ведь там точно так же сломали в определённый момент обратную совместимость: сделали string = UnicodeString вместо AnsiString
kazalex
постоялец
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Сообщение kazalex »

hinst писал(а):Фича говно хотя бы потому, что она ломает обратную совместимость

В нормальном коде не ломает.

В доке дельфей, с незапамятных времён, говорилось, что несмотря на то, что сегодня тип String это строка в которой каждый символ равен одному байту, завтра это может измениться. Поэтому, если вы хотите писать переносимый код, то в обычных ситуациях следует всегда использовать String и Char, а когда требуется использовать сроки с однобайтовыми символами, то это нужно указывать явно, то есть использовать AnsiString и AnsiChar. Кто доку читал, тот и не заметил перехода на юникод. Кто не читал, тот сам себе злобный буратино.
Последний раз редактировалось kazalex 03.09.2015 00:12:05, всего редактировалось 1 раз.
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

kazalex писал(а):читать тут, последний абзац.


Насколько я помню, warning'и эти ни в Delphi ни в Lazarus'e не видны при чтении кода. Только если компиляцию запустить.
kazalex
постоялец
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Сообщение kazalex »

Mirage писал(а):Насколько я помню, warning'и эти ни в Delphi ни в Lazarus'e не видны при чтении кода. Только если компиляцию запустить.

Тот кто пишет код, обычно его компилирует, и на предупреждения должен реагировать соответственно.

Добавлено спустя 9 часов 58 минут 7 секунд:
hinst писал(а):Раньше string это был AnsiString а теперь string это не AnsiString

Твои опасения напрасны. Только что собрал транковый 3.1.1, String становится UnicodeString'ом только после переключения режима: {$modeswitch unicodestrings} или {$mode delphiunicode}

Добавлено спустя 14 минут 7 секунд:
А вот лазарю придётся подтягивать совместимость с новыми строками и речь не только о LCL. Сейчас, когда лазарь показывает подсказку по сигнатуре функции, он берёт эту информацию из декларации, но не учитывает, что в одном модуле String может означать AnsiString, а в другом UnicodeString.
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Сообщение Сквозняк »

kazalex писал(а):p.s. Я не могу сказать, что без строк с информацией о кодировке невозможно жить, но с ними всё же лучше

При сложении двух ансистрингов - ничего хорошего. Прибавляешь одни данные а что прибавится - решит компилятор исходя из своих заморочек. А вдруг при конвертации из кодировки А в кодировку Б окажется что в Б такого символа нет? Мы все знаем как работают системные конвертаторы в таком случае - меняют всю непонятную информацию на свой мусор.
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Я в своём проекте активно использую класс TIniFile, в некоторых местах явно задавая строки в нём через Utf8Encode, а в некоторых - забивая на это, поскольку идентификаторы всегда в латинице, и кодировка там плоскопараллельна.

Вопрос: можно ли в этом классе задать кодировку, чтобы всегда интерпретировал как Utf-8? Файлы конфигурации должны быть одни и теже для Виндовс и Линукс.

Вопрос: аналогично с TStringList. Что будет при вызове метода SaveToFile ? Файлы должны быть совместимы между Виндовс и Линукс версиями. Можно ли явно задать для TStringList кодировку Utf-8?
Что будет при работе с проперти этого класса Text если разные его строки в разной кодировке?

Или я должен для обеспечения обратной совместимости копипастить эти классы к себе в проект, заменяя все объявления на RawByteString ?

Главный вопрос: какого бибипа это включено по умолчанию, в то время, как даже длинные строки нужно активировать вручную чтобы не сломать обратную совместимость?
По моему просвещённому мнению, AnsiString (по крайней мере в режиме objfpc) должен быть равен RawByteString, и переключаться на системную кодировку директивой компилятора
kazalex
постоялец
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Сообщение kazalex »

Сквозняк писал(а):При сложении двух ансистрингов - ничего хорошего

При сложении строк одного типа потеря данные невозможна по определению.

Сквозняк писал(а):Прибавляешь одни данные а что прибавится - решит компилятор исходя из своих заморочек.

Неверное предположение. Компилятор принимает решение о конвертировании исходя из информации о типе строк.

Сквозняк писал(а):А вдруг при конвертации из кодировки А в кодировку Б окажется что в Б такого символа нет?

То есть речь идёт о сложении вдух строк в различной кодировке. Тут всё будет зависеть от того, какая строка ожидается в результате. Сперва компилятор преобразует каждую из строк в юникод-представление, чтобы избежать потери данных, а затем сложением получает строку в юникоде. Следующим шагом будет преобразование юникод-представления в кодировку результирующей строки. Та часть символов, что не может быть представлена в этой кодировке будет заменена согласно стандарта на символ-заменитель, обычно это "?" для однобайтовых строк. То есть, если кириллицу попытаться представить в виде LatinString, то кроме символов-заменителей ничего не получится. Тут в другом вопрос, а зачем пытаться это делать, то есть зачем человеку в здравом уме писать MyString := LatinString(MyCyrillicString);? Так ведь и к iconv можно претензии предъявить, что она не может сделать "win1251" -> "iso-8859-2".
Mikhail
энтузиаст
Сообщения: 565
Зарегистрирован: 24.10.2013 16:06:47

Сообщение Mikhail »

Вот такой код будет работать?

Код: Выделить всё

procedure Test(var s: string);
var a: AnsiString(866);
begin
...
 s:=a;
end;

var s, s1: AnsiString(1251);
begin
 ...
 Test(s);
 ...
 s1:=s1 + s;
end.

kazalex
постоялец
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Сообщение kazalex »

Mikhail писал(а):Вот такой код будет работать?

Нет. Тут я вижу две ошибки:
1. Неправильная декларация типов строк
2. Передача в процедуру параметра не соответствующего типа

В остальном, всё должно компилироваться с кучей предупреждений.
Ответить