Длинное обсуждение про UTF-8 без BOM и Free Pascal

Планы есть. Но что вы имеете в виду?

Как минимум поддержку всех модулей вроде Graph и CRT, а не только голого паскаля. Полноценную работу с кодировкой UTF-8 в консоли, правильные концы строк при выводе в консоль, избавиться от BOM в начале файлов. Если в винде многие программы их переваривают, то в линуксе всё наоборот и в UTF8-файлах, а тем более в чистом ASCII, BOM категорически не рекомендуется.

Ну и для меня очевидно, что в UTF-8 Byte-Order-Mark не нужен, поскольку там всегда один и тот же порядок байтов: от битов к младшим.

Например Ы имеет номер 0x42B = 10000101011b в юникоде, что составляет 11 значимых битов, значит кодируется двумя байтами по маске 110xxxxx 10xxxxxx: 1101 0000 1010 1011 = D0 AB. То есть в первый байт попали старшие пять бит кода, а во второй младшие шесть бит.

То есть, дело как раз не в оболочке, а во всём остальном.

А напомните, BOM при сохранении исходников в оболочке или при создании файлов с помощью ReWrite(f)?

И какая разница - какие разделители в консоли - их же всё равно никому не видно?

А напомните, BOM при сохранении исходников в оболочке или при создании файлов с помощью ReWrite(f)?

Не знаю. Но в линуксе не должно никаких быть, да и в винде в идеале тоже. Насколько я помню всё-таки rewrite не должен его добавлять, иначе это было бы вообще крайне странно. Вроде и не добавляет, но вы проверьте на всякий случай.

А вот оболочка при сохранении в файл добавляет BOM, даже если там изначально был и остался только чистый ASCII и это тоже плохо. При открытии файла, оболочка в первую очередь должна предполагать UTF-8, но если декодирование файла как UTF-8 обнаружило некорректные последовательности, тогда уже пользователю можно показать диалог и предложить выбрать кодировку. BOM не нужен, поскольку в UTF-8 есть характерные последовательности байт, которые ни с чем не перепутать.

При таком поведении оболочки, ей BOM будет не нужен. Другим программам в линуксе он тоже не нужен, а иногда вообще ломает компиляцию.

Если вывод просто читать, то не видно, но в юникс-подобных ОС активно используется перенаправление вывода в файлы или на вход другим программам. Представьте себе, что программа на паскале генерирует код на другом языке программирования, компилятор которого считает \r на конце строк синтаксической ошибкой?

В обучении наоборот выигрывает, поскольку в нём есть и нормально работают указатели. В ABC они для галочки, а в Python вообще нет. Кроме того, у fpc гораздо лучше совместимость с классическим паскалем, описанным (почти?) во всех учебниках.

а что по вашему значит “нормально работают”? как я понимаю, pabc вообще имеет отличный от старых паскалей подход к указателями тк реализован на платформе .net но каких-то существенных проблем лично я в этом не вижу

1 лайк

Ну а теперь представьте, что имеется отлично работающий код в fpc код, активно использующий указатели. В pABC net он скомпилируется? Вот вам и ответ.

то есть по вашему pabc должен поддерживать целый воз всего ранее реализованного? в чём тогда ценность языка, если предлагается писать на нём в точно таком же стиле, как и на “старых” паскалях?

1 лайк

Если есть какие-то конкретные чёткие пожелания - пишите их в Issue в разделе ide. По одному Issue на каждое пожелание.

Оболочка под Linux не запускается.

Visual Studio также добавляет к исходникам BOM - у нас так же.

Под Linux пользуйтесь VS Code с плагином PascalABC.NET - там всё без BOM.

Речь идет о массовом обучении информатике, преимущественно в средних учебных заведениях. Зачем там какие-то указатели? Их нет в школьной программе. Вообще нет. С ними знакомятся те, кто выбирает С/С++, да и то в целях олимпиадного программирования. В РАВС указатели есть, но используют их крайне редко, поэтому можно считать, что они там для некоторой условной совместимости, насколько о ней можно говорить в .NET-среде. И да, указатели фактически не нужны в языках, построенных на современной ссылочной объектной модели.

Что до совместимости с “классическим паскалем, … в учебниках” - сейчас уже мало кто читает эти учебники, а классический паскаль мёртв. Какая нужда “гальванизировать труп” (с) ?

И снова: как это связано с обучением информатике? Кто хочет и дальше ездить на паровом локомобиле - пусть ездит. Это не повод ставить на современный автомобиль паровой котел.

Ну и что? Надо же и своё соображение иметь. Зачем копировать некорректное поведение?

Я так понимаю, что планируется сделать так, чтобы запускалась? Тогда не помешает и поменять поведение в таких ситуациях.

Это которая тащит с собой половину браузера Chrome? Спасибо, не надо.

Но раз даже MS в своих более новых редакторах отказались от неверного поведения, вам-то зачем его тащить?

В том, чтобы старый код работал без виртуалки с DOS и имел доступ к возможностям современного железа, в частности 32 и 64-битным регистрам.

И вроде ABC позиционируется как подходящий не только для школ, но и для ВУЗов, а в них указатели уж точно являются обязательной темой изучения.

В современном программировании без указателей никуда. Это правильнее сравнить с установкой на современный автомобиль руля.

Их даже в C++ не рекомендуют использовать. Там для этого есть все средства. А указатели в паскале настолько убоги сами по себе, что лучше про них вообще не рассказывать.

Да кому нужен старый код с DOS? Я понимаю, что на Западе почему-то озаботились меньшинствами, но работающие с DOS - это даже не меньшинства, это просто сектанты. Еще не хватало их ублажать.

Не являются. По крайней мере там, где могут начинаться с РАВС. А где нужны указатели, с первого же семестра дают С.

Да? А примеры можно, когда в современном программировании" есть нужда писать паскалевский код с указателями? Или это так, поговорить?

Чем вам BOM так не угодил то? Если файлы неправильно читается - это проблема программы, не знающей о кодировке, в которой он сохранён.

Если вам дадут файл видео, с кодеком, не установленным у вас, что будет адекватнее - просить ещё одно видео, другого формата, или установить кодек?

И то что UTF8 сивместимо с ASCII если использовать только первые 127 символов - это приятная плюшка, но в какой серьёзной ситуации вам понадобится читать текстовый файл кодировкой, которая может неправильно прочитать некоторые символы файла?

Особенно считая что для названий подпрограмм, классов и т.п. можно использовать буквы любого языка - программы прочитанные с помощью ASCII могут быть неюзабельны и без BOM.

Особенно считая что для названий подпрограмм, классов и т.п. можно использовать буквы любого языка - программы прочитанные с помощью ASCII могут быть неюзабельны и без BOM.

Так делать нельзя. То, что такая возможность теоретически где-то существует, не значит, что её допустимо использовать.

но в какой серьёзной ситуации вам понадобится читать текстовый файл кодировкой, которая может неправильно прочитать некоторые символы файла?

Компилятору языка программирования в общем случае вообще нет дела, в какой кодировке файл с программой. Он знает, например, что файл может содержать такие-то ключевые слова и прочие токены (в ASCII естественно), разделенные пробельными символами (только ASCII, естественно. В UTF-8 их слишком много, чтобы все распознавать).

Теперь представьте себе что он видит вместо директивы var a: integer что-то вроде \xEF\xBB\xBFvar a: integer:

Слово \xEF\xBB\xBFvar он не знает и возвращает синтаксическую ошибку. Делает он это абсолютно правильно и справедливо, поскольку он не какой-то текстовый редактор, а компилятор, то есть его задача — это распознавать синтаксис конкретного языка программирования, в который всякий не-ASCII бинарный мусор не входит.

При этом, это никак не мешает ему пропускать комментарии, содержащие UTF-8 или принимать строки, внутри которых UTF-8, поскольку для этого что-то знать об этой кодировке не нужно, достаточно просто найти открывающий символ комментария, то есть (* или { и пропустить всё до закрывающего *) } символа, при необходимости учитывая вложенные конструкции.

С учётом этого, текстовые редакторы, работающие с кодом ни в коем случае не должны пихать BOM в UTF-8 файлы, поскольку они этим создают синтаксические ошибки на ровном месте. Может MS VS так делает, поскольку она прибита гвоздями к компилятору той же фирмы, где мелкомягкие могли специально прописать исключение, чтобы \xEF\xBB\xBF пропускался, но это никак не делает это допустимым для других текстовых редакторов, поскольку другие компиляторы не обязаны пропускать эти байты и далеко не всегда это делают.

Например, если вы работаете не с одним компилятором паскаля, а с несколькими, что мешает открыть в редакторе PascalABC.net файл, изначально предназначенный для Borland Pascal, подредактировать там что-то, а затем попытаться скомпилировать в Borland Pascal?

Из-за существующего на данный момент бага в итоге файл не скомпилируется ни в PascalABC.net — потому что он не поддерживает некоторые возможности нормального паскаля, ни в Borland Pascal — потому что добавлены мусорные байты в начало файла.

Да и вообще, что мешает пользователю открыть в редакторе код на любом языке программирования, хоть на C, хоть на Python? Может у него уже открыт PascalABC.net и ему не хочется загружать какой-то ещё редактор для того чтобы быстренько добавить точку с запятой или ещё что-то подобное?

Это нормально, когда текстовый редактор портит код? По-моему, нет. А по-вашему?

я спросил в чём ценность конкретно pabc. Вы осознаёте, что несмотря на нахождение в семействе паскаль-языков, pabc.net всё таки ОТДЕЛЬНЫЙ и САМОСТОЯТЕЛЬНЫЙ язык, а не утилита для компиляции всего подряд?

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

В наше время это уже не оправдано. Компилятор, который знает только про ASCII - это устаревший мусор.

char.IsWhiteSpace именно этим занимается.

Да, такие проверки затратнее чем ch.Code=32, но для разделения на токены они вполне подходят - первая стадия компиляции всё равно обычно самая быстрая.

А что мешает написать программу на Java, а затем попытаться запустить её как JavaScrips? Может то, что это языки, не имеющие общей спецификации и похожие только в самых базовых моментах синтаксиса?

Не только в трурбо-паскале нет большинства .Net фич - в PascalABC.Net тоже нет кучи всего из турбо-паскаля, к примеру многих устаревших директив. Написание кода, используя НОД фич таких разных языков - это мазохизм, хватит его тут пропагандировать.

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

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

Но пусть программист нарушит этот принцип и оставит строку с UTF-8 символами. Компилятор просто вставит байты этой строки в секцию данных как есть, без какой-либо интерпретации, ему вообще не важно, UTF-8 там, CP1251 или вообще CP437 досовская какая-нибудь. А уже дело программиста знать кодировку строки и вызывать строковые функции, которые работают именно с этой кодировкой. Например можно проверить локаль, и если она *.UTF-8 то выкинуть строку на stdout как есть, а если нет, то вначале вызвать iconv и перевести в другую кодировку. Если программа запущена на Windows, то дело программиста найти и подключить dll или самому написать конвертер из UTF-8 в UTF-16 прежде чем передавать функциям Windows API, но в любом из этих случаев компилятору не требуется знать в какой кодировке исходный файл. И это хорошо, что он её не знает, поскольку это позволит работать с любой кодировкой, не меняя и не трогая компилятор. Мало ли может вы захотите тем же компилятором собрать программу для другой ОС, где нет поддержки UTF-8 или вообще модуль для начального загрузчика.

Заметьте что это никак не запрещает использовать в программе любые библиотеки, в том числе и работающие с UTF-8 и другими кодировками.

char.IsWhiteSpace именно этим занимается.

Усложнение компилятора — это плохо. Кроме того, внезапное изменение поведения существующей программы — это вообще недопустимо, а с появлением новых стандартов юникода это может произойти. Набор базовых элементов языка программирования должен быть строго фиксированным. Например за пробелы он должен считать собственно пробелы, табы, переводы строк и может быть ещё \r \v \f всякие и всё. Список должен быть закрытым на момент появления спецификации языка.

Может то, что это языки, не имеющие общей спецификации и похожие только в самых базовых моментах синтаксиса?

Перечитайте вопрос. Я имел ввиду использование редактора pABC.net отдельно от компилятора для правки текстовых файлов, в тч кода.

Это что за директивы такие, если не секрет?

@Admin , если вас аргументы на словах не убеждают, то вот вам пример где наличие BOM в UTF-8 файле откровенно вредно:

flat assembler version 1.73.27 (1089705 kilobytes memory)
wow64chs.asm [1]:
;
processed: 
error: illegal instruction.

Так себя ведёт не только fasm, но и большинство других компиляторов.

Это баги других компиляторов. Мы то тут причем?

Это не баг, а фича: BOM не является заранее определенным элементом синтаксиса языка, поэтому вызывает синтаксическую ошибку. Вот другое поведение было бы как раз багом.

Речь идёт о PascalABC.net IDE, то есть не о компиляторе, а о текстовом редакторе. Как видим из вышесказанного, в его теперешнем состоянии он плохо пригоден для написания кода на других языках, поскольку вставляет мусорные байты при сохранении.

Я предлагаю это исправить. Нужно всего одно маленькое изменение — не вставлять BOM при сохранении файла в UTF-8 и тем более в чистом ASCII.

Кстати, fasm поддерживает метки и прочие символы из юникодных символов (а на самом деле, вообще любых символов — он encoding agnostic). Например некоторые так маскируют BOM, вставляя эту строчку в начало файла (перед знаком = есть невидимый символ):

="utf-8"

Таким образом объявляется мусорная переменная с именем  <BOM> и значением utf-8, которая потом нигде не используется и BOM больше не вызывает синтаксическую ошибку. Но на мой взгляд, гораздо разумнее всё-таки не ставить такие костыли, а поменять настройки текстового редактора так, чтобы он никогда не вставлял BOM в UTF-8, если его явно об этом не попросить.