Pull to refresh

Comments 19

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

Далее немного оффтопа, но тоже про проблемы русской локали.

В свое время, при обновлении GCC для AVR до версии 5.4.0 (из репозитория Debian 12) столкнулся с проблемой сборки своего древнего и давно работающего проекта. Ну мало ли, при обновлении версий чего не бывает, особенно при скачке сразу через несколько версий... Создал минимально возможный тестовый проект, но все равно, при попытке сборки, упорно выскакивала ошибка линкера:

make all 
Building target: test_c.elf
Invoking: AVR C++ Linker
avr-gcc -Wl,-Map,test_c.map,--cref -mrelax -Wl,--gc-sections -mmcu=atmega328p -o "test_c.elf" ./src/main.o   
collect2: fatal error: ld terminated with signal 6 [Аварийный останов], core dumped
compilation terminated.
*** stack smashing detected ***: terminated
make: *** [makefile:79: test_c.elf] Ошибка 1
"make all" terminated with exit code 2. Build might be incomplete.

В итоге, "всемогущим методом тыка" выяснил, что все нормально собирается, если при вызове компилятора отключить русскую локаль путем замены команды вызова компилятора

avr-gcc

на

LANG="" avr-gcc

Похоже, что разработчики avr-gcc с некоторого момента времени вообще перестали его тестировать на работу под русской локалью, ибо в противном случае ошибку просто невозможно было не заметить.

Это на самом деле баг в binutils-avr, который существовал там по той причине, что версия binutils там на самом деле очень древняя (но патчи от Atmel есть только для этой древней версии); в апстриме binutils проблему починили ещё в 2017 году. В конце 2023 года баг внезапно пофиксили, но до Debian stable фикс пока ещё не дополз (зато вроде бы вошёл в Ubuntu 24.04 LTS).

Вспомнил фидошные времена: "Меня видно? ет!" :)

А на днях, перекидывая текстовый файл с компа на телефон (1251 кодировка, Android 8) вдруг увидел, что при просмотре на телефоне в тексте пропали заглавные русские буквы, могут отображаться пробел, спецсимволы, английские.. удивился, давно такого не встречал.

Удивлён, что 1251 до сих пор где-то используется. Я думал везде уже на юникод перешли.

Наивный вопрос от не-программиста (ну то есть Hello World на экран выведу, лампочкой на Ардуине помигаю, "sudo apt-get" в терминале напечатаю одним пальцем).

SQLite - это же база данных такая, я правильно понимаю? А зачем базе данных выводить ошибки на местных языках? И вообще знать, какая в системе установлена локаль?

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

Поэтому ошибка БД, коль уж она произойдет, необработанным исключением предстает пред ясные очи пользователя. И считается, что будет несколько лучше, если она будет на понятном языке, а не на иероглифах. Чтобы юзер мог хотя бы саппорту прочитать, что на экране написано.

Чтобы юзер мог хотя бы саппорту прочитать, что на экране написано.

В данном случае, как я понимаю, приложение ничего юзеру не показывало, а молча не запускалось. Саппорту пришлось лезть в логи, где уже ему пришлось разбираться с незнакомым языком. Ну и ошибка "not en error, все в порядке" это отдельный показательный пример мышления программистов.

Для баз данных не так важно "выводить ошибки на местных языках". Гораздо важнее правильно сортировать списки по алфавиту, причем не только в выводе но и внутри БД (в индексах). И часто получается, что символы к кодировке (в том числе в юникодных) в лучшем случае отсортированы для одного языка. А для той же кириллицы алфавитов разных языков целая куча.

Могут быть другие моменты, типа привязки формата дат к локали, но это уже не должно на самом деле "утекать" в БД. В 1999 году, когда я только начинал программировать я замучался исправлять баг, который был связан именно с датами - я передавал данные из строки напрямую в SQL запрос и происходила путаница между форматами DD.MM.YYYY и MM/DD/YYYY. Очевидно, что в моём случае ошибка была в том, что в БД надо было передавать дату в формате ISO 8601 и не зависеть от локали.

Гораздо важнее правильно сортировать списки по алфавиту, причем не только в выводе но и внутри БД (в индексах).

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

Вот сколько я с локалями не сталкивался, всегда есть какие-то проблемы. И мой опыт говорит, что всегда должен быть промежуточный фильтр данных, хотя бы виде ассоциативного массива "данные1" => "данные2". И работать надо только через него, заранее забив вручную заведомо корректными парами значений.

Причем это поголовно, везде... Берешь какую-нибудь гео-ip базу данных, пытаешься её данные связать со своими, вроде всё работает, проблем нет. А потом ты случайно узнаешь, что в одной базе города нормально англифицированы, а в другой часть из них почему-то транслитом. Причем не все! И когда звезды совпадают - ты ловишь проблему, что "город не найден" при том, что он заведомо есть в обоих базах.

Читая статью, всё ожидал проблему, когда на разных локалях разделитель целой и дробной частей десятичной записи чисел будет разным (точа или запятая). Сам не раз с такой проблемой сталкивался, когда какой-нибудь sscanf не работает как нужно. И даже когда сам был научен проблемами с ним, встречал аналогичные проблемы в чужом коде.

Не боитесь баян порвать? И, вообще, сия проблема до сих пор в ходу? Лет так 25-27 назад тот самый sscanf уже был "не торт".

Проблема никуда не делась. Поведение этой функции менять никто не собирается, чтобы не сломать обратную совместимость. А более новые функции (тот же to_chars) или не знают, или не могут по каким-то причинам использовать.
И да, если мне не изменяет память, всякие std::cin и прочие istream тоже страдают от проблемы зависимости от локали.

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

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

Сменил язык на телефоне, не верю глазам своим — заходит, привязал фейсайди для авторизации — заходит. Аггггрх!)

Сменил язык обратно — все равно заходит. Зарепортил банку, посмотрим, что ответят

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

Помню, в четвёртом Norton Commander просмотровщик текстовых файлов имел возможнось просмотра файлов в различных форматах, а также автодетект этих самых форматов . Так вот самая веселуха была в том, что если просматривался обычный текстовый файл с русскими буквами в нём, то он иногда детектировался как один из "не тех" форматов (не помню уже, какой) — и одной из особенностей этого формата было то, что последовательность байт, соответствующая русским буквам "оп", была каким-то служебным маркером и потому не показывалась.

А потом неопытные юзера очень сильно удивлялись, когда просматривали какой-нибудь прайс-лист, в котором упоминались "соверменные европейские компьютеры" или что-нибудь типа того....

В то же время где-то в недрах зависимостей:

if (languageCode.equals("ru")) { halt(); }

Когда американский программист узнает, что в мире существуют другие локали, у него в голове происходит такой разрыв мозга, что он пишет по этому поводу целую статью.

Sign up to leave a comment.