FPC 3.0 RC1 announced

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

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

Re: FPC 3.0 RC1 announced

Сообщение kazalex » 07.09.2015 22:45:01

Сквозняк писал(а):В том случае, если данные перед сложением не конвертируются.

Строки одного типа перед сложением не конвертируются, опять же, по определению.

Сквозняк писал(а):Потому что компилятор правит алгоритм программы

Компилятор делает ровно то, о чём ты его просишь и ничего не добавляет от себя.

Сквозняк писал(а):А вдруг программа должна складывать в ansistring строки в разных, в том числе в несуществующих, кодировках?

Несуществующих кодировках, это как?

Сквозняк писал(а):Это шутка такая? В Utf-8 большинство значений массива 0..2^48 не используются! А в ansistringe используется любая комбинация байтов которую в неё можно записать. Поэтому потери при такой технологии запланированы заранее.

Сквозняк писал(а):Порча информации на ровном месте, о которой программист компилятор совсем не просил.

Строка, кроме данных, содержит идентификатор кодовой страницы, поэтому её безопасно можно конвертировать в юникод-представление. После чего такие строки складываются и делается обратное преобразование в кодировку результирующей строки. Вот на этом этапе потеря данных возможна, но (!), за это отвечает программист. Если он будет конвертировать кириллицу в латиницу, то потери будут вне зависимости от способа конвертирования. Кто в ладах с головой будет так делать?

Сквозняк писал(а):Управляющие символы очень даже нужны, а когда они пересекаются с теми символами что можно написать на клавиатуре или увидеть на экране, то происходят такие сопли как в баше, типа экранирований экранирований пробелов, наклонных чёрточек и неадекватного разбора текста.

Это, я так понимаю, претензия к стандарту Unicode?

Добавлено спустя 11 минут 55 секунд:
Mikhail писал(а):Ну не всегда нужна конвертация

Так если не нужна, кто заставляет использовать?
Mikhail писал(а):конвертация через юникод неоптимальна

Она только через юникод и оптимальна, иначе таблиц маппинга нужно будет иметь столько, что мало не покажется (в XP, доступных кодировок, примерно, 134. Если конвертировать не через юникод, то для прямого маппинга нужно почти 18 тысяч кодовых таблиц).
Mikhail писал(а):При грамотном постороении приложения строки с кодировкой просто не нужны

Я выше давал пример, где строки с информацией о кодировании самое то. Помимо этого, у строк есть такая штука, как COW, чего нет у байтовых массивов, и иногда это очень нужная фича.
Mikhail писал(а):Это несколько облегчает написание спагетти-кода, поэтому это вредное нововведение.

Спагетти-код провоцирует событийное программирование, а отнюдь не encoding aware строки.
kazalex
постоялец
 
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Re: FPC 3.0 RC1 announced

Сообщение Cheb » 08.09.2015 00:48:27

В любом случае, фича нужная и полезная, но введена через заднее место.
Ибо ломать обратную совместимость есть ЗЛО. Красивый такой выстрел себе в ногу.
Совершенно непонятно, почему разработчики ФП !внезапно! отказались от державшейся уже больше десятилетия традиции, когда любые новые фичи, влияющие на обратную совместимость, требовали явного включения директивой компилятора.
Зачем было выдёргивать коврик из под AnsiString вместо того, чтобы ввести, например, какую-нибудь EncodingAwareString, параллельную ей?
Я понимаю зачем это для {$mode delphi}
Я совершенно не понимаю зачем это для {$mode objfpc}

Потом, обязательно нужен ключ компилятора, который бы превращал все случаи неявного преобразования кодировки в ошибки, облегчая портирование старого кода.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 862
Зарегистрирован: 06.06.2005 15:54:34

Re: FPC 3.0 RC1 announced

Сообщение kazalex » 08.09.2015 01:21:03

Cheb писал(а):Ибо ломать обратную совместимость есть ЗЛО. Красивый такой выстрел себе в ногу.

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

Cheb писал(а):Потом, обязательно нужен ключ компилятора, который бы превращал все случаи неявного преобразования кодировки в ошибки, облегчая портирование старого кода.

Компилятор, в случае неявного конвертирования, генерирует предупреждение. Правда, на текущий момент он отслеживает не все случаи, но это пока ещё и не релиз. Ну а для генерирования ошибок по предупреждениям на преобразования достаточно директив:
Код: Выделить всё
{$warn IMPLICIT_STRING_CAST Error}
{$warn IMPLICIT_STRING_CAST_LOSS Error}
{$warn EXPLICIT_STRING_CAST Error}
{$warn EXPLICIT_STRING_CAST_LOSS Error}
kazalex
постоялец
 
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Re: FPC 3.0 RC1 announced

Сообщение SSerge » 08.09.2015 06:44:12

Cheb писал(а):Я совершенно не понимаю зачем это для {$mode objfpc}


Чтобы работал такой код:

Var s:UnicodeString;
s1:cp1251String;

...

s:='Строка на албанском языке';
s1:=' и строка на японском языке';

writeln(s+s1);


причем без изменения кода и перекомпиляции на ОС с разными локалями. Вкупе с извращением "cp866 консоль, cp1251 всё остальное, UTF16 файловая система". Это я про Windows если чсто.
SSerge
энтузиаст
 
Сообщения: 909
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: FPC 3.0 RC1 announced

Сообщение Снег Север » 08.09.2015 08:10:30

Чтобы избежать конвертации не нужно делать присваиваний и сложений строк в разной кодировке. Ваш Кэп.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2672
Зарегистрирован: 27.11.2007 16:14:47

Re: FPC 3.0 RC1 announced

Сообщение Mikhail » 08.09.2015 08:21:04

kazalex писал(а):Так если не нужна, кто заставляет использовать?

Компилятор заставляет. Вот, допустим, строка из внешней (чужой) библиотеки приходит в cp866, а я работаю в cp1251, но... строка содержит символы только из первой половины кодовой таблицы и конвертация, в этом случае, не требуется. Я об этом знаю, а вот компилятор нет и будет выполнять не нужную работу.

kazalex писал(а):Если конвертировать не через юникод, то для прямого маппинга нужно почти 18 тысяч кодовых таблиц).

Не нужно, т.к. таблицу для маппинга можно получать динамически. И вообще, задача конвертации из любой кодировки в любую надумана - это не нужно, ибо это преобразование необратимо. Есть задача конвертации из какой-либо кодировки в юникод и наоборот. Причем первое преобразование всегда возможно, а вот второе нет.

kazalex писал(а):Я выше давал пример, где строки с информацией о кодировании самое то.

Где? Вы же сами говорили, и я полностью с этим согласен, что преобразования нужно делать по границам компонентов, а этот новый тип провоцирует устраивать свалку из строк в разной кодировке в пределах одного компонента и, даже, "ядра" программы.

kazalex писал(а):Помимо этого, у строк есть такая штука, как COW, чего нет у байтовых массивов, и иногда это очень нужная фича.

:?:

kazalex писал(а):Спагетти-код провоцирует событийное программирование, а отнюдь не encoding aware строки.

Спагетти-код провоцирует много чего, в том числе и вот такие строки.

PS В целом причина появления строк с кодировкой в FPC понятна и закономерна - декларируется совместимость с Delphi. Но ИМХО, это вредная и не нужная фича. Но если очень чешется, то нужно разрешить только автопреобразование из строки с кодировкой в юникод ибо он может быть выполнен однозначно, все остальные авто-преобразования нужно запретить.
Mikhail
энтузиаст
 
Сообщения: 544
Зарегистрирован: 24.10.2013 16:06:47

Re: FPC 3.0 RC1 announced

Сообщение Cheb » 08.09.2015 08:47:06

достаточно директив:

Сапасибо! Сохранил, буду применять :D

Никаких преобразований не будет происходить до тех пор пока ты работаешь со строками одного типа.

И я теперь должен ломать голову и перелопачивать тоны давно забытого кода потому что записывал Utf-8 в AnsiString ПОТМУ ЧТО СТАНДАРТНЫЕ КЛАССЫ ТИПА TStringList ДРУГОГО НЕ ПОНИМАЛИ ?
Все эти рекомендации звучат как утончённое издевательство. И именно по этой причине.
Раньше, прямая запись юникодной строки в стринглист вела к потерям (ибо трактовалась Utf16 -> cp1251) поэтому, естественно, я везде явно вставлял Utf8Encode() . Но, эй, это же не проблема, да?
А ЕСЛИ Я К ЭТОМУ ЗНАЧЕНИЮ СНАЧАЛА ДОБАВЛЯЛ ПРЕФИКС ТИПА AnsiString, В КОТОРОМ ЗАВЕДОМО БЫЛА ТОЛЬКО БАЗОВАЯ ЛАТИНИЦА? Потому что, положа руку на с ердце, кого волнует кодировка когда у тебя там записан паскаль-совместимый идентификатор, или плюсик, или, упаси боже, циферки. Конкатенация этого всегда выполняется без потерь, поскольку таким строкам плевать на кодировку. ВЕДЬ ПРАВДА? :evil:

Но ИМХО, это вредная и не нужная фича.

Вот именно. Ограничили бы её {$mode delphi} - никто бы слова поперёк не сказал.

Добавлено спустя 10 минут 1 секунду:
P.S. Типичный пример заподлянки:

Код: Выделить всё
function MyFancyIntToStr(num, characters: integer): AnsiString; //при нуле заполняет все позиции нулями
var
  t: TStringList;
...
  t.Add(MyFancyIntToStr(kyu_num, 3) + Utf8Encode('  кьюбеев /人◕ ‿‿ ◕人\'));


На самом IntToStr - надумано. На деле это мог быть гарантированно-базово-латинский идентификатор

Добавлено спустя 2 часа 19 минут 31 секунду:
{$warn IMPLICIT_STRING_CAST_LOSS Error}

Ещё раз спасибо за информацию :D
Очень помогает выпалывать старый говнокод.

Если бы только компилятор не падал с Internal error 200309041 на половине компиляции моего проекта :cry:
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 862
Зарегистрирован: 06.06.2005 15:54:34

Re: FPC 3.0 RC1 announced

Сообщение kazalex » 08.09.2015 13:26:29

Mikhail писал(а):Вот, допустим, строка из внешней (чужой) библиотеки приходит в cp866, а я работаю в cp1251, но... строка содержит символы только из первой половины кодовой таблицы и конвертация, в этом случае, не требуется.

Проблема видится мне надуманной, но всё же... Нет ничего проще:
Код: Выделить всё
type

String1251 = type AnsiString(1251);
String866 = type AnsiString(866);

var

s1251 : String1251;

Function getString866 : String866;
Begin
Result := 'hello, world!';
End;

Begin

RawByteString(s1251) := getString866;           // присваивание без преобразований
SetCodePage(RawByteString(s1251), 1251, False); // восстановление кодовой страницы

End.

Mikhail писал(а):Не нужно, т.к. таблицу для маппинга можно получать динамически.

Кроме того, что это всё равно получается кодирование через юникод, так ещё и таблицы такие не нужны т.к. обычно текст не конвертируется из одной кодировки в другую. Наиболее частый случай это преобразование юникода в некое представление и обратное преобразование, т.к. все давно отказались от внутреннего представления текста в виде байтов определённой кодировки покрывающей лишь малую часть пространства юникод.
Mikhail писал(а):И вообще, задача конвертации из любой кодировки в любую надумана - это не нужно, ибо это преобразование необратимо. Есть задача конвертации из какой-либо кодировки в юникод и наоборот. Причем первое преобразование всегда возможно, а вот второе нет.

Я не совсем понимаю с чем ты споришь, ведь я говорю ровно о том же.
Mikhail писал(а):Где? Вы же сами говорили, и я полностью с этим согласен, что преобразования нужно делать по границам компонентов, а этот новый тип провоцирует устраивать свалку из строк в разной кодировке в пределах одного компонента и, даже, "ядра" программы.

Пример тут. И конечно, новый тип строк ничего такого не провоцирует. В дельфийских приложениях никакого ужаса с появлением таких строк не случилоcь. Я уверен, что большиству с ними и столкнуться-то не придётся, т.к. область их применения довольно узка. Это просто удобный механизм, сродни выделенным классам кодировок TEncoding.
Mikhail писал(а)::?:

Что именно непонятно? Потребность в COW или сравнение с байтовыми массивами?
Mikhail писал(а):Спагетти-код провоцирует много чего, в том числе и вот такие строки.

При использовании данных строк не возникает ни каких дополнительных ветвлений, вся логика сосредоточена перед глазами читающего. Со спагетти-кодом нет ничего общего.
Cheb писал(а):И я теперь должен ломать голову и перелопачивать тоны давно забытого кода потому что записывал Utf-8 в AnsiString ПОТМУ ЧТО СТАНДАРТНЫЕ КЛАССЫ ТИПА TStringList ДРУГОГО НЕ ПОНИМАЛИ ?

Не должен, компилятор сам всё покажет.
Cheb писал(а):Раньше, прямая запись юникодной строки в стринглист вела к потерям (ибо трактовалась Utf16 -> cp1251) поэтому, естественно, я везде явно вставлял Utf8Encode() . Но, эй, это же не проблема, да?

Нет никакой проблемы. Единственное, что там может быть это лишние преобразования, но к потерям данных они не приведут.
Cheb писал(а):А ЕСЛИ Я К ЭТОМУ ЗНАЧЕНИЮ СНАЧАЛА ДОБАВЛЯЛ ПРЕФИКС ТИПА AnsiString, В КОТОРОМ ЗАВЕДОМО БЫЛА ТОЛЬКО БАЗОВАЯ ЛАТИНИЦА? Потому что, положа руку на с ердце, кого волнует кодировка когда у тебя там записан паскаль-совместимый идентификатор, или плюсик, или, упаси боже, циферки. Конкатенация этого всегда выполняется без потерь, поскольку таким строкам плевать на кодировку. ВЕДЬ ПРАВДА?

Это я не распрарсил.
Cheb писал(а):Если бы только компилятор не падал с Internal error 200309041 на половине компиляции моего проекта :cry:

Ну так он ещё не релизнулся, самое время стункуться в багтрекер.
kazalex
постоялец
 
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Re: FPC 3.0 RC1 announced

Сообщение Сквозняк » 08.09.2015 15:08:05

kazalex писал(а):Компилятор делает ровно то, о чём ты его просишь и ничего не добавляет от себя.

И как тогда отключить в файле перекодирование чтобы он не добавлял ничего от себя?
Несуществующих кодировках, это как?

Смесь текста с управляющими символами.
Строка, кроме данных, содержит идентификатор кодовой страницы, поэтому её безопасно можно конвертировать в юникод-представление

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

Это будет делать компилятор в который заложены идиотские инструкции. ansistring может содержать например utf-8 текст перемешанный с символами не используемыми в utf-8, которые компилятор посчитает символами 8 битной кодировки.
Сквозняк
энтузиаст
 
Сообщения: 800
Зарегистрирован: 29.06.2006 22:08:32

Re: FPC 3.0 RC1 announced

Сообщение kazalex » 08.09.2015 15:25:01

Сквозняк писал(а):И как тогда отключить в файле перекодирование чтобы он не добавлял ничего от себя?

Использовать однотипные строки.
Сквозняк писал(а):Смесь текста с управляющими символами.

Ни каких проблем. Используешь обычные AnsiString (хоть с указанием кодировки, хоть без), записываешь туда всякий мусор. При сложении таких строк преобразования выполняться не будут т.к. строки одного типа, а между однотипными строками преобразования не нужны.
Сквозняк писал(а):Значит чтобы строки не перекодировались и не портились, из каждого ansistring нужно удалить индентификатор кодовой страницы?

Нет, достаточно не смешивать разнотипные строки. Компилятор принимает решение о необходимости конвертирования ориентируясь на тип строки, а не на идентификатор кодовой страницы. Кодовая страница нужна для того, чтобы знать, как именно конвертировать данные строки в юникод.
Сквозняк писал(а):Это будет делать компилятор в который заложены идиотские инструкции.

Ещё раз: компилятор не делает ничего сверх того о чём его просят. Весь процесс конвертирования строк полностью подконтролен программисту.
kazalex
постоялец
 
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Re: FPC 3.0 RC1 announced

Сообщение Cheb » 08.09.2015 16:36:05

, самое время стункуться в багтрекер.

http://bugs.freepascal.org/view.php?id=28639 8)
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 862
Зарегистрирован: 06.06.2005 15:54:34

Re: FPC 3.0 RC1 announced

Сообщение Cheb » 10.09.2015 22:42:53

Убедился, что имя файла у TFileStream - по прежнему не юникодное, а вовсе даже AnsiString - и разочарованно отложил в длинный ящик. Попробую снова в 2016-м.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 862
Зарегистрирован: 06.06.2005 15:54:34

Re: FPC 3.0 RC1 announced

Сообщение kazalex » 11.09.2015 13:04:02

Cheb писал(а):Убедился, что имя файла у TFileStream - по прежнему не юникодное, а вовсе даже AnsiString - и разочарованно отложил в длинный ящик

RTL ещё не полностью готова, это верно, хотя базовые файловые функции, через которые работает TFileStream, уже поддерживают новые строки. Но в лазаре сейчас можно включить поддержку UTF-8 в RTL (там компилятору передаётся ключик меняющий кодировку входных данных - файлов + делается глобальный дефайн "EnableUTF8RTL", после чего в RTL переключается дефолтная кодировка AnsiString на CP_UTF8).
kazalex
постоялец
 
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Re: FPC 3.0 RC1 announced

Сообщение vada » 11.09.2015 14:25:04

С кодировкой это проблемы раннего становления фри паскаля. В стародавние времена когда было заявлено "компилируется везде" и была заложена бомба.
Помнится эта концепция сильно критиковалась. Вот оно! Работает! Конца края не видно.
С переносом проекта с XP на 7, нахлебался.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: FPC 3.0 RC1 announced

Сообщение debi12345 » 11.09.2015 20:55:54

В делфи-варианте любая операция со строкой — потенциальное преобразование, о том и речь. Я надеюсь, это отключаемо?

Хм, хотите кошмариться (либо ручное выделение-освобождение памяти, либо фиксированная длина) со строками как в С ? Ну-ну ..
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5638
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Пред.След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 3

Рейтинг@Mail.ru