LINUX.ORG.RU

Написал статью «Как жить если у вас юникод»

 ,


5

4

Собственно, сабж. Статья про то самое, что мы с Eddy_Em не могли осилить в прежние времена. В этом году я это, внезапно, осилил. Ну и написал статью.

https://saahriktu.ru/pdf/kak_jit_esli_u_vas_yunikod.pdf

★★★★★
Ответ на: комментарий от hateyoufeel

посмотрел, он сделал функцию майн на сях

#include <Rts.h>
extern StgClosure ZCMain_main_closure;
int main(int argc, char *argv[])
{
 RtsConfig __conf = defaultRtsConfig;
 __conf.rts_opts_enabled = RtsOptsSafeOnly;
 __conf.rts_opts_suggestions = true;
__conf.keep_cafs = false;
 __conf.rts_hs_main = true;
 return hs_main(argc,argv,&ZCMain_main_closure,__conf);
}
sergej ★★★★★
()

Ты аннотацию на ЛОРе неправильно сделал. Пользователи на ЛОРе с юникодом живут припеваючи. Надо было сразу написать, что статья для программистов. В самой статье сразу написано:

Несмотря на то, что такие языки программирования как Python, Ruby и Free Pascal хорошо поддерживают юникод при работе с ним могут возникать трудности у программистов на C и C++.

Ну и сразу для C++ могу предложить QString из QtCore, там юникод и перекодировки из коробки.

hobbit ★★★★★
()
Ответ на: комментарий от cumvillain

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

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от sergej

Си ушел в ембедед и системные штуки

Никуда он не уходил. На C/C++ продолжают писать те же браузеры и офисы. И кучу другого десктопного софта тоже. Просто они теперь чаще всего вагон и тележку сторонних библиотек используют. Но это зависит от масштабов проекта.

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

И тут вина не юникода совсем.

Создатели юникода усложнили всё введением «кодепоинтов». Если бы они их не вводили бы и один символ/глиф кодировался бы одним кодом, то wchar_t* решал бы все проблемы. А так он решает только половину проблем.

saahriktu ★★★★★
() автор топика

Написал статью «Как жить если у вас юникод»

Шутка

Юникод предоставляет коды символов.
Так не проще ли каждому слова языка присвоить код.

-------------------------------------------------------
Юникод «произрастает» из проблемы использовать в тексте слова в разной кодировке.

А это в свою очередь «произрастает» от того, что все программисты не могут понять, что текст не обязательно должен быть представлен в виде строки.
Текст может быть представлен в виде некоего объекта и тогда неожиданно «объект» позволит передать и семантику.

Forum0888
()
Ответ на: комментарий от saahriktu

Создатели юникода усложнили всё введением «кодепоинтов».

Тогда пространство юникода давно бы кончилось.

Если бы они их не вводили бы и один символ/глиф кодировался бы одним кодом, то wchar_t* решал бы все проблемы. А так он решает только половину проблем.

А почему в других языках нет такой проблемы? Почему только сишники жидко насрали себе в штаны?

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

почему в других языках нет такой проблемы?

Как нет? Выше, например, был приведён действительно рабочий пример с получением длины юникодной строки только в Rust'е. В том же Python'е с этим не справляются ни len(), ни wcwidth.wcswidth() (хотя для ряда данных результаты корректные; но не для всех данных, да).

saahriktu ★★★★★
() автор топика
Последнее исправление: saahriktu (всего исправлений: 1)
Ответ на: комментарий от saahriktu

рабочий пример с получением длины юникодной строки

Я тебе уже в 5 раз пишу тут: для юникодных строк понятие длины зависит от контекста. Это может быть, как минимум:

  • Количество байт
  • Количество кодпоинтов
  • Количество глифов
  • Количество печатаемых символов
hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Мы тут уже не первую страницу обсуждаем получение кол-ва печатаемых и непечатаемых символов. Т.е., по сути:

  • Кол-во того, что занимает ровно один кодепоинт, включается в итоговую сумму. Даже если это невидимые символы или табуляция.
  • Составные символы из нескольких кодепоинтов составляются и тоже считаются.

Т.е. речь о полном аналоге того, как функции типа len() работали во времена однобайтных кодировок.

saahriktu ★★★★★
() автор топика
Последнее исправление: saahriktu (всего исправлений: 2)
Ответ на: комментарий от Forum0888

ИМХО юникод удобен в использовании лишь для вэб.

Или если ты хочешь открыть русско-еврейский словарь.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от saahriktu

Т.е. речь о полном аналоге того, как функции типа len() работала во времена однобайтных кодировок.

И ещё раз напишу тебе: для юникода нет полного аналога функции len() для однобайтовых кодировок. Просто нету. Прекрати уже эту шизофрению тут всем нести.

hateyoufeel ★★★★★
()
Ответ на: комментарий от saahriktu

Так это Вы раскритиковали Си

Ну, да, потому что C – довольно говняный язык.

у меня в нём такого нет даже через wchar_t*. Перечитайте обсуждение выше.

Ты перечитай то, что тебе написали. wchat_t – днище и его надо закопать и забыть как страшный позор. Для C таки есть библиотеки для работы с юникодом. Просто это не стандартная библиотека.

Вот, прямо от создателей юникода: https://icu.unicode.org/

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от zurg

Зато на хачкелле под 8051 писать можно без проблем. Я не шучу, если что.

а что там есть сейчас(вообще, не только 8051)? был вроде ivory, но давно не обновлялся

Ivory странный. По сути, C натянутый на eDSL в хачкелле. И всё ради «Ivory does not allow nullable pointers, unbounded memory access, or heap allocation». Ну то есть, я могу себе представить, где это нужно, но лучше что-то ещё взять.

А так, из опенсорсного есть Copilot для софта и Clash для FPGA. Второй особенно прекрасен.

Насколько я понимаю из общения с хачкеллотусовкой, каждая контора делает свой eDSL и не особо желает им делиться, потому что бабло :)

hateyoufeel ★★★★★
()
Ответ на: комментарий от X512

А при чём тут UTF-16? Во-первых, внутреннее и внешнее представления строк - это разные вещи. В том же Free Pascal’е в UnicodeString каждый кодепоинт кодируется двуми байтами, но при этом ввод и вывод происходят в UTF-8. Во-вторых, wchar_t в линуксе не 2 байта, а 4.

В UNIX-like никто wchar_t … не пользуется.

Пользуется.

saahriktu ★★★★★
() автор топика
Последнее исправление: saahriktu (всего исправлений: 3)

Вообще я не до конца понимаю зачем это нужно:

$ cat unicode.c
#include <stdio.h>

int
main(void)
{
    printf("Зачем вообще нужен этот wchar_t?\n");
    return 0;
}
$ gcc -o unicode unicode.c
$ ./unicode > file
$ file -bi file
text/plain; charset=utf-8

Ну и зачем мне нужен твой wchar_t?

cumvillain
()
Ответ на: комментарий от sergej

зачем передавать wchar_t?

Передавать данные как-то все равно придется. И о том, что не стоит наружу выпускать типы переменной разрядности еще нужно догадаться.

Так-то как внутри программа будет данные представлять это ее личное дело (с оглядкой на переносимость). Иногда уместен и UTF-16 внутри, так всякие xml-движки типа zorba делают (на сколько я понимаю это компромисс по скорости/памяти). Но IO в основном в UTF-8 организуется и прежде чем выбирать отличное от этого представление нужно хорошенько подумать, иначе по всему проекту быстро расползутся конвертации между кодировками.

dvetutnev
()
Ответ на: комментарий от cumvillain
$ grep -E "wchar_t" python3-3.11.4/* -R | wc -l
1204
$

И там далеко не только относящийся к винде код, а вообще.

python3-3.11.4/Include/cpython/initconfig.h:    wchar_t **items;
python3-3.11.4/Include/cpython/initconfig.h:    const wchar_t *item);
python3-3.11.4/Include/cpython/initconfig.h:    const wchar_t *item);
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *dump_refs_file;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *filesystem_encoding;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *filesystem_errors;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *pycache_prefix;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *stdio_encoding;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *stdio_errors;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *check_hash_pycs_mode;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *program_name;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *pythonpath_env;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *home;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *platlibdir;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *stdlib_dir;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *executable;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *base_executable;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *prefix;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *base_prefix;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *exec_prefix;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *base_exec_prefix;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *run_command;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *run_module;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t *run_filename;
python3-3.11.4/Include/cpython/initconfig.h:    wchar_t **config_str,
python3-3.11.4/Include/cpython/initconfig.h:    const wchar_t *str);

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от dvetutnev

Но Майкрософт как всегда решил «мы пойдем своим путем», сделала свой API в UTF-16

Авторы Юникода поначалю заявляли что 16 бит хватит всем. Это уже потом Юникод расширили до 32 бит.

X512 ★★★★★
()
Ответ на: комментарий от saahriktu

Конкретно для линуксоидов пишущих под GNU/Linux вообще никаких проблем от использования wchar_t нет.

Проблема в том, что это пустая трата памяти (в том числе и для русского языка) а также дополнительные конфертации кодировок повсюду (сторонние библиотеки обычно используют char* и UTF-8).

X512 ★★★★★
()
Ответ на: комментарий от saahriktu

Не всем нужны сторонние библиотеки.

Нужны, если нужна работа с Unicode. В C её нет, тебе четыре страницы об этом пишут :D

Для работы с Unicode нужны:

  • Нормализация
  • Работа с лексемами
  • Работа с code point’ами

wchar_t со скрипом решает последнюю проблему. Для того чтобы выводить utf-8 текст в utf-8 консоль он просто не нужен :D

cumvillain
()
Ответ на: комментарий от cumvillain

из-за венды

Так тут выше утверждали, что char* кроссплатформеннее, поскольку в wchar_t софт может попробовать записать 4 байта и на винде будет переполнение.

По этой логике, кстати, wchar_t* хуже для винды подходит.

А так, да, в софте могут быть одновременно и char* строки, и wchar_t*.

Однако, кое-кто утверждал, что, якобы, wchar_t* только в специфически виндовом софте используется. А это не так.

В т.ч. в коде Python'а можно найти функции, которые требуют wchar_t* аргументы, и это не специфически виндовый код.

python3-3.11.4/Modules/posixmodule.c:        if (wcslen(wide) != length) {
python3-3.11.4/Modules/posixmodule.c:    if (wcslen(wide) != length) {
python3-3.11.4/Modules/posixmodule.c:        v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
python3-3.11.4/Modules/posixmodule.c:    size_t n = wcslen(pszFile);
python3-3.11.4/Modules/posixmodule.c:        len = wcslen(path->wide);
python3-3.11.4/Modules/posixmodule.c:                                       wcslen(wFileData.cFileName));
python3-3.11.4/Modules/posixmodule.c:    PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath));
python3-3.11.4/Modules/posixmodule.c:    result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
python3-3.11.4/Modules/posixmodule.c:    buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * (wcslen(path->wide) + 1));
python3-3.11.4/Modules/posixmodule.c:        path_len = wcslen(path_wide);
python3-3.11.4/Modules/posixmodule.c:    size = path_len + 1 + wcslen(filename) + 1;

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от saahriktu

В т.ч. в коде Python’а можно найти функции, которые требуют wchar_t* аргументы, и это не специфически виндовый код.

Лол, в этом же файле:

static PyObject *

#ifdef MS_WINDOWS
    wchar_t *path_strW;
#else
    const char *path_str;

Прекращай нести бред, wchar_t в cpython исключительно ради венды.

cumvillain
()
Ответ на: комментарий от cumvillain

Там же:

 * path_converter accepts (Unicode) strings and their
 * subclasses, and bytes and their subclasses.  What
 * it does with the argument depends on the platform:
 *
 *   * On Windows, if we get a (Unicode) string we
 *     extract the wchar_t * and return it; if we get
 *     bytes we decode to wchar_t * and return that.
 *
 *   * On all other platforms, strings are encoded
 *     to bytes using PyUnicode_FSConverter, then we
 *     extract the char * from the bytes object and
 *     return that.
cumvillain
()
Ответ на: комментарий от saahriktu

ОС + стандартные библиотеки - это уже не голое железо.

Что такое «стандартные библиотеки» в контексте Linux? Glibc – стандартная библиотека? А если у меня Musl? Как насчёт glib, который есть почти везде? А icu?

hateyoufeel ★★★★★
()

Статью не читал. Поясните в двух словах, уникод это хорошо или плохо?

А то я уже лет десять полностью на нём и вот засомневался.

utanho ★★★★★
()