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

я спросил в чём ценность конкретно 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, если его явно об этом не попросить.

Вы сами правильно сказали, то что вы объяснили о fasm - это костыль.
Вместо исправления проблемы - речь идёт про её обходы. Это неправильно, не зависимо от правильности BOM.

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

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

Вам так трудно исправить баг, про который вам подробно рассказали и на сто рядов доказали, что это именно баг? Если такой же баг есть в Visual Studio, это что, значит, что его исправлять нельзя?!

Чем плохо использовать ABC IDE для редактирования кода на паскале, если этот код потом предполагается компилировать Free Pascal? Подсветка синтаксиса паскаля, хоть и не идеальна совместима с fpc, но ведь лучше чем никакой, правильно? В идеале в IDE вообще должна быть опция, какой компилятор вызывать при нажатии F9, чтобы можно было сделать полную интеграцию ABC IDE с компилятором FPC.

Вместо исправления проблемы - речь идёт про её обходы.

Ну да. правильный способ исправления проблемы — изменить текстовый редактор так, чтобы он не вставлял BOM в UTF-8. Но для некоторых редакторов (MS Notepad, PascalABC.net IDE и тд) это невозможно или сложно. поскольку такой настройки нету.

Если до MS вряд ли реально достучаться, то у ABC есть хотя бы форум.

Вообще стандарт Unicode не запрещает BOM, хотя и не советует его добавлять. Просто он бесполезен, но не значит, что запрещен. В стандарте также есть рекомендация не добавлять / не убирать его при редактировании.

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

В некоторые компиляторы добавлены костыли для пропуска BOM, но ведь не во все, поэтому в коде он категорически не рекомендуется.

В языках, в спецификации которых не описано, что BOM допустим, его ни в коем случае не следует ставить, но к сожалению некоторые редакторы ставят.

Фактически BOM в начале потока это BOM и ничто другое. Это в середине он так воспринимается в виде костыля, для случаев когда например два файла конкатенировали.

В спецификации языка и не должно быть написано ничего про BOM. Компилятор должен открыть и прочитать файл. Компилятор в целом может требовать что-то, что не определено в спецификации. Например, gcc нормально работает с файлами UTF-8 и BOM, но не переваривает переменные в UTF-8.

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

Я посмотрел код текстового редактора. В принципе, я Вас понимаю.

К сожалению, редактор взят As is из Sharp Developа. И - увы - сохранение с BOM там запаяно. Если бы была какая-то опция, мы бы каким-то образом сделали чтобы это можно было переключать.

Я также посмотрел редактор последнего Lazarus. Он нормально открывает файлы с BOM и если их изменить и сохранить, то тоже сохраняет с BOM. К чести сказать, новые файлы он сохраняет без BOM.

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

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

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

Все работают с BOM. Вы хотите без BOM. Нужна опция. И нужен кто-то кто аккуратно это сделает.

Как показывает практика, эта универсальная фраза в 100% случаев приводит к тому, что вопрос снимается с повестки дня. Никто не хочет что-то делать, но все готовы без устали обвинять и критиковать.

В смысле, вы хотите сказать, что кому-то этот BOM нужен и полезен?

Тогда вопросов нет,

Но вы уверены, что им действительно кто-то пользуется в том смысле, что у кого-то есть use-case, где, если ABC IDE начнёт сохранять без BOM, придётся ставить другую программу и его добавлять?

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

BOM

Тот же fpc судя по документации использует BOM для определения кодировки исходников: “if the file starts with an UTF-8 BOM, then the source file codepage is UTF-8, otherwise … the source file codepage is set to CP_ACP (for backward compatibility with previous FPC versions)” (FPC Unicode support - Free Pascal wiki). :laughing:

1 лайк

Ну так это проблемы fpc, нам-то они тут зачем? Если я купил кофеварку, почему ее производитель должен от меня выслушивать упреки, что она не позволяет варить пельмени?

Вы, извините, как тот мужик из бородатого советского анекдота, который просил переселить его в другую комнату общежития, потому что “из этой видна раздевалка в женской душевой”:

  • так не видно же ничего!
  • а Вы на шкаф залезьте…

Catcher нравится fpc. Catcher зацепился за то что BOM никому не нужен, а pabc его ставит и это нужно всенепременно поправить. Я ему отвечаю, что тот же fpc как раз использует BOM для определения UTF-8 кодировки.

Другими словами, если мы хотим совместимости, то pabc как раз правильно делает что добавляет BOM в utf-8 файлах, иначе их fpc не сможет нормально интерпретировать.

Я нигде не писал, что pabc что-то должен делать по другому, я как раз не вижу тут проблемы. А учитывая, что IDE pabc вообще под linux нативно не работает, а под виндой поведение соответствует поведению того-же VS - на мой взгляд вообще все вполне корректно.

Но чукча видимо не читатель…

1 лайк

Зря они конечно так сделали, но кроме BOM указан вариант {$codepage UTF8}, который всё же лучше, ну и ещё есть вариант ещё лучше — не иметь в исходном коде никаких символов вне ASCII, тогда не будет нужна ни директива, ни BOM, ни что-то иное. Как указано по ссылке, BOM используется только, если такой директивы нет.

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

Я и так много букв написал, почему это некорректно.