LINUX.ORG.RU

В стандарт C предложено внести лямбды и defer из golang

 , ,


5

6

Привет, ЛОР!

Я тут тебе немного покушать принёс. Как ты, наверное знаешь, не за горами выход нового стандарта языка C – C23. Среди прочих вкусностей, таких как лямбды в стиле C++, в этот стандарт предложено добавить механизм defer, аналогичный существующему в языке Go.

Ссылка на предложение: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2895.htm

В случае, если этот стандарт будет принят, будет возможно написание вот такого кода:

p = malloc(N);
defer { free(p); }

Где аргументом оператора defer является анонимная функция. Так же возможны более сложные варианты использования:

enum { initial = 16, };
double buffer[initial] = { 0 };
...
size_t elements = 0;
double* q = buffer;
defer [orig = q, &q]{ if (orig != q) { free(q); }};
...
// increase elements somehow
...
// adjust the buffer
if (elements > initial) {
    double* pp = (q == buffer) ? malloc(sizeof(double[elements])) : realloc(q, sizeof(double[elements]));
    if (!pp) return EXIT_FAILURE;
    q = pp;
}
...

Учитывая всё это, скоро в C больше не будет нужно использовать goto вообще нигде, даже для очистки ресурсов при ошибке. Так заживём, ЛОР!

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

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

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

Даже там дела со строками лучше чем в C.

Чем? Как только нужны строки длинней ограничения счётчика, что нужно чуть менее, чем всегда, начинается тотже онанизм с указателями, что и в С (PChar это называется ЕМНИП). Или там какие-то уже другие строки завезли?

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

Нормальных, если в смысле в которых можно ходить как по массиву символов, то нет (wchar_t и весь этот мультибайт ИМХО == боль). Если нормальными считать строки, где в RunTime есть вменяемый набор функций для работы с UTF-8 строками, то есть в любом более-менее современном ЯП (по крайней мере из тех, что я интересовался).

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

Прекращай демагогию, все отлично понимают о чём речь.

Ты вот не понимаешь.

Хранить строки как последовательность символов, заканчивающихся нулём - вполне себе разумный вариант

Да. Только строкового типа в C всё равно нет. Вот смотри:

struct str { char *data; } s;  // Это строка

char *p; // Это указатель

Так разница понятна?

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

Как только нужны строки длинней ограничения счётчика, что нужно чуть менее, чем всегда, начинается тотже онанизм с указателями,

В FPC ограничение 4 гигабайта (32 бита на счётчик). Это покрывает 99.99% использования строк.

Нормальных, если в смысле в которых можно ходить как по массиву символов, то нет (wchar_t и весь этот мультибайт ИМХО == боль).

В поцкале есть Utf8String. Во всяких хацкеллах и прочих рустах тоже.

Другой вопрос, что да, хер знает что считать символом. ü – это один символ или два? Потому что может быть записан и так и так.

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

Если нормальными считать строки, где в RunTime есть вменяемый набор функций для работы с UTF-8 строками,

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

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

Так разница понятна?

Это декоративная разница. Ты в очередной раз палишься скриптописательскими привычками. Си - язык системного программирования, прятать нужные вещи куда-то внутрь тут будет неудобно. Впрочем тебе никто не мешает использовать свой struct str.

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

Опять ты за своё. Библиотек огромное количество, выбирай нужную или напиши свою, если ты такой особенный что нужное тебе - оказалось никому за 50 лет кроме тебя не нужно.

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

Ты в очередной раз палишься скриптописательскими привычками.

Обернуть разные вещи в типы, чтобы случайно не обосраться – это скриптописательство? Сколько CVE ты в час плодишь? Расскажи нам.

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

Кому неудобно? Почему неудобно? Кто тебе такую хероту сказал? И как сиситемное программирование здесь играет какую-то роль? В Pascal и Lisp есть строки, но ОС на них это писать никому не помешало.

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

Крутяк! А другие библиотеки будут другие строки использовать? И ты предлагаешь конвертировать между разными строковыми типами? Мальчик, ты вообще код пишешь?

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

Кому неудобно? Почему неудобно?

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

Обернуть разные вещи в типы, чтобы случайно не обосраться – это скриптописательство? Сколько CVE ты в час плодишь? Расскажи нам.

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

Крутяк! А другие библиотеки будут другие строки использовать? И ты предлагаешь конвертировать между разными строковыми типами?

Повторю, выбирай те, которые тебе удобны. Если утебяэто вызывает затруднения - иди в PHP.

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

В FPC ограничение 4 гигабайта

Вот именно, что только в FPC. В паскале «вообще», насколько я в курсе, этот момент не истолкован и в конкретном компиляторе может быть размер и 255 на строку.

В поцкале есть Utf8String. Во всяких хацкеллах и прочих рустах тоже.

Так я следующим предложением это и написал.

Потому что может быть записан и так и так

В частности поэтому в большинтве языков и нельзя манипулировать строками «побайтово» в стиле Си. Только разной стоимости рантайм обёртки.

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

язык тут ни при чём

В слове «дописать». В соверменных языках строки изначально жёстко utf-8 и весь рантайм заточен именно на это.

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

В FPC ограничение 4 гигабайта

То есть в строке из пары символов больше половины занимает счетчик? Какой ужас.

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

Неудобно тем, кто пользуется всеми возможностями языка, а не боится их и не пытается от них спрятаться.

Ну, то есть, ты боишься структурок и сделать нормальный API?

Скриптописательство это когда ты хочешь отгородиться от всех деталей и не планируешь их использовать.

Нет, это не скриптописательство. Тебя Царь, кажется, изнасиловал.

CVE плодят обычно как раз скриптописатели, лезущие в нормальный язык.

Нет, их плодят программисты на C.

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

в конкретном компиляторе может быть размер и 255 на строку.

В каком именно? Их сейчас живых ровно два: FPC и Delphi. И что-то мне кажется, второй тоже такими проблемами не страдает.

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

Глянул в доку Embarcadero. Там вообще всё весело. Т.е.

  • старые, которые раньше были String, теперь ShortString,
  • неюникодные, про которые ты говоришь - AnsiString,
  • wchar - WideString
  • дефолтный UnicodeString (на который теперь тип string алиасится)
  • C-style PChar/PWideChar тоже никто не отменял.

Кратко, резюмируя - полная задница. Однако, если обойтись дефолтными string (алиас UnicodeString), то в принципе, даже и неплохо.

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

Тут дело не в строках, а в том, что в т.н. «современных языках» рантайм это часть языка, а это сделано потому, что они ориентированы на решение прикладных задач и не хотят привязываться к чему-то нативному. Поэтому у них в рантайме что-то вообще может быть. У Си противоположна идеология, он с собой несёт почти ничего своего, почти все используемые функции - нативные функции системной библиотеки ОС. Да, есть всякие printf, которые договорились во всех ОС делать похожими (и то - они отличаются между реализациями). Так что, это в системной библиотеке может быть, а может не быть поддержка utf8, сам язык в этом отношении нейтрален. В двойных кавычках (единственное что очно именно часть языка) можно и utf-8 строки писать, языку опять же всё равно.

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

Ну, то есть, ты боишься структурок и сделать нормальный API?

Твои стукрурки и АПИ резко начнет сосать в рекурсивных алгоритмах. Адресная арифметика в Си — это одна из киллер фич языка.

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

Тогда весь тред не имеет смысла, потому что лямбды и defer - тоже сахар, в общем-то.

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

Ну, то есть, ты боишься структурок и сделать нормальный API?

API будет у твоей библиотеки, когда ты её напишешь. А тут речь идёт о нативных операциях над данными.

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

Нет, это не скриптописательство.

Нет, это именно оно.

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

тут речь идёт о нативных операциях над данными.

Что такое «нативные операции над данными»? Ей богу, ты какую-то днищенскую ересь несёшь. Прекрати так делать.

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

Глянул в доку Embarcadero. Там вообще всё весело. Т.е.

Знаешь, очень похоже на нынешнюю ситуацию в Rust. Там вот ровно то же самое.

Кратко, резюмируя - полная задница. Однако, если обойтись дефолтными string (алиас UnicodeString), то в принципе, даже и неплохо.

Ну да, так и должно быть. Дефолтный сценарий для 99% случаев плюс специальные штуки. Всё ок.

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

Нет, не начнёт. Если ты не смог нормальный API для строк осилить, то подпускать тебя к указателям на пушечный выстрел тоже не стоит. А то на доску почёта сишников попадёшь.

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

Нет, ересь несёшь ты. Основа Си - манипуляции числами. Сравнить число в такой-то переменной с такой-то константой, прочесь из памяти из ячейки с таким-то номером (указатель-число) численное значение, записать, перейти по такому-то адресу (указатель-число на метку или функцию), итд. Для типовых алгоритмических задач (циклы, функции) сделан специальный наглядный синтаксис, чтобы не орудовать одним goto. Всё остальное - кастомные абстракции, реализованные библиотекой. У библиотеки может быть API итд, но не надо её приписывать языку.

Если ты не готов программировать в такой идеологии - Си тебе не нужен. Можешь перейти на С++ хотя бы, он похож, но уже идеологически оперирует абстракциями (как ты любишь) а не байтами в памяти. А вообще твой путь пхп, там не получится случайно в память залезть и напортачить.

firkax ★★★★★
()

Давно пора.

Про лямбды правда не понял что это и зачем. Я против лямбд. Просто defer надо. Без всяких скобок.

char *s = malloc(256);
defer free(s);
Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 2)
Ответ на: комментарий от firkax

Основа Си - манипуляции числами.

Откуда ты это берёшь? Сам придумываешь? Керниган и Ритчи даже чисел произвольной точности не осилили в язык добавить. Язык для манипуляции числами — это фортран. Вот там да, числа так числа.

Ну и я повторю: указатели — это не числа. Даже в стандарте C они отдельно от чисел описываются.

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

Ну в моём понимании defer должен отрабатывать по выходу из блока а не функции. То бишь все статическое и по сути тривиально переписывается на код с goto, только читать проще.

Конечно если всякие блямбды не тащить. Что там за лямбды я не знаю.

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

Библиотек огромное количество
оказалось никому за 50 лет кроме тебя не нужно

Смотрите, дети. Это и есть то самое логическое мышление, которым так гордятся программисты.

thesis ★★★★★
()

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

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

Про лямбды правда не понял что это и зачем. Я против лямбд.

Бггг.

Просто defer надо. Без всяких скобок.

А теперь посмотри, что там наверчено вместо «просто».

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

Си хорош своей стандартностью и простотой

Отличный вброс! Поддерживаю!

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

Вот стоит где-то не уточнить очевидную вещь - как некоторые сразу об неё спотыкаются.

Числа, конечно, не в математическом понимании, а в информационном. То есть перечислимое множество значений, записанное в удобно-кратное для процессора количество бит. В современных реалиях это 8, 16, 32, 64.

Ну и я повторю: указатели — это не числа.

Это синтаксический сахар для чисел. Лишь чуть более абстрагированный чем 'a' которое хоть и написано символом, на самом деле число 65. Ну и + механизм выявления багов с помощью строгой типизации. Прочесть байт по адресу 123: c = *(unsigned char*)123. Повторюсь, если такие конструкции вызывают у тебя дискомфорт - Си не для тебя.

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

Числа, конечно, не в математическом понимании, а в информационном.

Что такое «информационное понимание» чисел?

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

Опять же, как это мешает задавать числа произвольной точности? Что если я хочу 4-битные числа (0..15)? Ada это может. И вот это реально язык для системного программирования. Прямо вот по самые гланды для него. А C – это какое-то недоразумение.

Это синтаксический сахар для чисел.

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

Прочесть байт по адресу 123: c = (unsigned char)123.

Я тебе скажу по секрету: такое же можно вообще на любом языке написать. Даже на Haskell!

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

Это синтаксический сахар для чисел.

Попустись. Уже выяснили, что это колебания вакуума.

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

Опять же, как это мешает задавать числа произвольной точности? Что если я хочу 4-битные числа (0..15)?

Ну, вообще для этого там есть синтаксис (битовые поля в структурах), но на мой взгляд он не особо нужен (и прячет нативную работу с памятью от программиста), и поэтому про него мало кто помнит. Если б не он, я бы сказал - делай библиотеку. Библиотеки есть для чисел почти любой разрядности. Ну, тут «библиотека» простая - `&15`, `>>4`, `<<4`.

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

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

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

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

Можно. Хранить строки как массив с произвольным доступом при выходе за границы которого наступает remote code execution – это хуже.

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

Ну, если ты идиот то у тебя будет код с выходом за границы. Пиши тогда на php, там всё само проверяется.

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

Ну, вообще для этого там есть синтаксис (битовые поля в структурах)

О! Так для этого структуры норм использовать, а для строк – нет? Ты уж определись. К – консистентность.

Ну и, к слову, как без перегрузки операторов использовать + и - для этих чисел?

Библиотеки есть для чисел почти любой разрядности. Ну, тут «библиотека» простая - &15, >>4, <<4.

Ты исповедуешь copy-paste driven programming? Тебе там за количество кода платят, что ли? Цент за символ или ты больше берёшь?

И как ты, например, 512-битные числа реализуешь через &15? Криптографию на таком писать – это огонь был бы. Особенно учитывая требования к коду с криптой, из-за которых его мало на каком языке можно писать.

Это артефакты оптимизации.

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

они увы необходимы для генерации более быстрого кода.

Расскажи мне, каким образом же такое поведение при сравнении указателей в 2022 году генерирует более быстрый код? Учитывая, что узкие места сейчас почти все лежат где-то в районе локов или постоянной ненужной долбёжки диска.

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

Не, проблема си - не освобождение ресурсов. Главная проблема - сишники, точнее понаехавшие ассемблерщики, физически неспособные понять что такое ЯП. У них всё на свете это биты (в запущенных случаях - числа), все абстракции - это сахар (как определяется синтаксический сахар они, конечно, не знают/не понимают), семантика языка - это «артефакты оптимизации» (ака неизбежное зло), а в целом всё непонятное - это скриптуха.

Но зато они пишут сверхбыстрый код! Который собирается и работает в удачную фазу луны на правильном компиляторе правильной версии с правильными флагами, и в который не надо пихать неправильные входные данные. А то сами дураки же, кто пихает, и вообще все сишные cve сделали засланные пхп-шники, а настоящий сишник - это зубр, свысока глядящий на суетящихся детей, чей ЯП не достиг полувека.

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

Ну, если ты идиот то у тебя будет код с выходом за границы. Пиши тогда на php, там всё само проверяется.

Разработчики Linux Kernel – идиоты? Разработчики OpenBSD? FreeBSD? Покажи пожалуйста не идиотов, потому что ошибки в строках постоянно и у всех.

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

Я хочу тобы этот кринж продолжался.

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

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

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

О! Так для этого структуры норм использовать, а для строк – нет? Ты уж определись. К – консистентность. Ну и, к слову, как без перегрузки операторов использовать + и - для этих чисел?

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

struct x {
  int a:1;
  int b:3;
  int c:4;
};

Поля a b c размером 1 3 и 4 бита.

Причём тут структуры для строк? Хотя ты конечно опять всё извратишь, но попробую объяснить. К строкам в си крайне часто (если не почти всегда) применяется адресная арифметика. Ты хочешь собственно адрес спрятать внутрь структуры, это тупо неудобно для большинства применений (потому что вместо s[i] придётся писать s.data[i], вместо s++ писать s.data++ итд, сам по себе идентификатор s будет годиться только для передачи его в какую-нить функцию аргументом - а это очень мало). Если тебе действительно хочется сделать opaque-тип для строк - делай структуру, никто не против. Но то, что ты главный способ обработки строк (адресную арифметику) хочешь убрать подальше - создаёт странное впечатление.

Насчёт «норм структуры использовать для битовых полей». Я прямо такого заявления не делал. Я сказал, что в си есть такой синтаксис, на радость тем кому это нужно. Сам - не пользовался (ну, там где я сам всё делаю а не чей-то код правлю), так что можешь это считать тоже неодобрением. Почему не пользовался, опять объясню в надежде на понимание. Я привык, что в Си оператор присваивания означает «записать значение справа от знака равно в lvalue слеваот знака равно», и ничего больше не делать. В случае, когда слева битовое поле, это правило нарушается: сначала идёт чтение байта (или больше), содержащего это поле, затем нужные биты в этом числе заменяются на то, что справа от знака равно, затем модифицированный байт записывается назад. Предпочитаю, чтобы подобная логика была явно указана в исходнике, а не подразумевалась. Тем более что с точки зрения итогового ассемблерного кода и скорости работы - получится одно и то же. Такое явное указание низкоуровневой логики везде - большое достоинство Си, а битовые поля из этой идеологии чуточку отходят.

И как ты, например, 512-битные числа реализуешь через &15?

Это было про 4-битные. Для 512-битных нужна библиотека с функциями сложения итд. В С++ можно даже перегрузить арифметические операторы, чтобы оно выглядело как обычная арифметика, в Си - нужно явно писать вызов функций. С одной стороны в этом минус: это не так наглядно в плане собственно арифметики. С другой - плюс: 512-битная арифметика неизбежно будет использовать malloc() и подобное внутри себя, и не очень хорошо, когда оператор сложения (плюс) упадёт из-за нехватки памяти (да и не понятно, куда слать эту ошибку).

вместо этого продвигая какую-то свою версию C, которая существует только в твоей голове.

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

Расскажи мне, каким образом же такое поведение при сравнении указателей в 2022 году генерирует более быстрый код? Учитывая, что узкие места сейчас почти все лежат где-то в районе локов или постоянной ненужной долбёжки диска.

Очевидно, можно сэкономить такт процессора на операции сравнения. А может быть и больше, если в итоге не придётся считать выражение с одной (или обеих) из сторон вообще. Да, это во многих случаях не даст заметного прироста, поэтому стоит разделить код на две категории: тот, который важно оптимизировать компиляторными оптимизациями (ставим ему -O2 или -O3, следим чтобы не было мест, которые оптимизатор может повредить - адресная арифметика через границы переменных, разыменование NULL, знаковые переполнения, использование неинициализированных переменных, параллельная работа с одной и той же памятью через указатели разного типа, последнее можно отключить -fno-strict-aliasing) и тот где это не особо нужно (ставим -O0 и пользуемся логически строгим поведением, не боясь попасть на какие-то грабли).

firkax ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.