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 вообще нигде, даже для очистки ресурсов при ошибке. Так заживём, ЛОР!

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

Ну да.

А насчёт патчей - ну так реформатируй обратно, при создании патча.

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

Да и какое это вообще может имееть значение при наличии indent? Не понравилось форматирование в чужих сырцах - натравил indent и всё стало хорошо.

Экий вы, батенька, анархист. Сейчас принято жесткое навязывание единственно верного форматирования на уровне чуть ли не компилятора (превед, go format). Вся прогрессивная общественность за это топит и бьёт по рукам отщепенцев.

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

превед, go format

Это потому что язык недавно появился. А C/C++ появились давно и на них уже написано много проектов в сильно разных стилях.

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

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

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

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

Так при вызове функций обычно не ставят. Пробел ставят между if/for/while/switch и скобкой. Там выглядит норм.

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

Я решил скобки унифицировать почему-то. И пробел после скобки делает код визуально как-то воздушнее и равномернее на мой вкус. Я ж говорю вкусовщина это всё. Как больше нравится - так и пиши, делов-то. Собственный эстетический комфорт важнее каких-то там стилей и правил всяких мимокрокодилов. Если мимокрокодилам не нравится - у них никто indent не отбирает.

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

Бгг. :) Кто бы сомневался.

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

Сишник, который считает, что срать мимо буфера — норма, суть просто быдлокодер. Ошибки бывают, я понимаю, но продолжать упираться, что у тебя в коде всё хорошо — дурной тон.

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

но отработать ситуацию ты как-то должен предсказуемым образом, а не как повезёт.

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

Сишник, который считает, что срать мимо буфера — норма

Я никогда такого не утверждал, вообще-то.

продолжать упираться, что у тебя в коде всё хорошо — дурной тон.

Где и когда я утверждал что-то подобное?

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

Но нет, вообще никто из них дальше этих нескольких строчек видеть напрочь неспособен.

И даже когда я сам написал, как на самом деле можно грамотно и с пользой обработать эту ситуацию, продолжаются вопли про «надо немедленно return/abort».

Прикол вовсе не в том, что ситуация в которой эта ошибка вообще может возникнуть полностью высосана из пальца. Весь прикол в том, что радетели за «безопасность» просто принципиально неспособны думать чуть шире чем идиотский паттерн «ошибка - делаем return/abort». Никто даже и не подумал предложить что-то типа очевидного if( ret < 0 ) goto out_rename.

Логично предположить, что по неким причинам, мимокрокодилов, топящих за безопасные язычки, волнует исключительно соблюдение неких формальных правил в сильно ограниченном scope, и абсолютно никак не волнует то, к каким эффектам во всём остальном это может привести.

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

Опять же о безопасности. Вот чисто ради прикола накатил раст, с большим трудом нашёл на жидхабе хоть что-то неабстрактное на расте (тупейший мост MODBUS TCP<>RTU) и запустил cargo build --release. Это чудесное поделие немедленно и без спросу полезло в интернет скачивать что-то с crates.io. Снёс раст нахрен. Такая вот у них забота о безопасности. Возможно это самая безопасная в смысле локальных ошибок программиста реализация MODBUS’ного моста, но про безопасность всего этого в целом они не задумались вообще ни на секунду. Мне софт написанный кренделями с таким образом мышления нафиг не нужен, будь он хоть абсолютно идеальным с точки зрения локальных ошибок в коде.

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

Ты так много букв написал за эти дни, вместо того, чтобы сразу сказать «да пох, демон некритичный, вероятность ошибки мала, я тупо забил; отсосите». А так у тебя странная ситуация - как обработать ошибку не знаешь _ты_, а идиоты при этом - _все остальные_. Еще и «безопасность» какая-то постоянно лезет.

ЗЫ. Я, кстати, точно помню, что натыкался на случай, когда вместо файла конфига какая-то дрянь (не помню, по-моему кривой скрипт установщика) создавала одноименный каталог. Так что это экзотика, но не невероятная.

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

не находит там "To: " и проваливается до перемещения файла.

Не находит, ага. В неинициализированном буфере, в котором может быть что угодно.

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

вместо того, чтобы сразу сказать «да пох, демон некритичный, вероятность ошибки мала, я тупо забил; отсосите»

Я это раз 10 уже написал.

как обработать ошибку не знаешь ты, а идиоты при этом - все остальные.

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

Еще и «безопасность» какая-то постоянно лезет.

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

создавала одноименный каталог.

Да, бывает. Создают всякое временное, для каких-то своих нужд. Но прикол в том, что эта софтинка слушает inotify на предмет mv файла в спул, а не создания. (mv/rename атомарная для юзерспейса операция, не надо заморачиваться с локами и пр.) Т.е. при создании директории в спуле данная функция с лажей вызвана просто не будет. И при сканировании спула при переподключении тоже не будет вызвана, потому что при сканировании вызывается только на regular файлы, которые могли появиться там пока связи не было или программа не работала. Так что даже случайное создание директории никак не приведёт к возникновению неприятной ситуации. Т.е. это надо специально и сознательно сделать mv some_directory /var/spool/xmppcd/out. Программ, которые случайно могут сделать именно mv директории в spool я не знаю ни одной. С таким же успехом можно всерьёз рассматривать вероятность замыкания отвёрткой дорожек на плате.

ЗЫ: Цель всей этой многодневное писанины, на самом деле изучение специфической группы любителей безопасных язычков, а вовсе не какой-то там спор ради чего-то там. Вот сколько сюда забрело их все до единого почему-то обладают каким-то туннельным зрением - «о, в этих строчках ошибка, надо return/abort». Для чего нужен этот код их вообще не интересует. И все совершенно одинаковые с одинаковым ходом мысли, как с конвейера какого-то. Ну интересно же - откуда вот этот весь трындец с современным типа прикладным софтом взялся и чем закончится.

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

Я тут в ютубе смотрел видео про паттерны, и там предложили довольно компактную реализацию std::function всего на 45 строчек и какие паттерны там используются для реализации.

https://gcc.godbolt.org/z/e46hdj1sE

fsb4000 ★★★★★
()

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

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

Зачем для этого штандартизаторы?

Чтобы не только в gcc работало. Хотя, пофиг. Главное, сделайте.

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

Нет, не одно и то же. Это будут разные указатели.

Во-первых, сугубо практический аспект: F000:FFF0 и FFFF:0000 - указывают на физический адрес FFFF0, но если ты попытаешься расположить там структуру длиннее 16 байт, то 16-й её байт по этим указателям будет лежать уже в разных местах физической памяти.

Во-вторых, даже если у тебя будут два указателя, которые ведут себя 100% эквивалентно (такого можно добиться на i386, если смапить одни и те же физические 2ГБ на два равноправных диапазона 00000000-7FFFFFFF и 80000000-FFFFFFFF - тогда старший бит указателя не будет ни на что влиять), то это всё равно буду разные указатели. Просто потому что разные. «Повезло», что ведут они себя одинаково, но это ничего не значит.

Ну и теоретическое: никто не говорил, что целое число, эквивалентное указателю - это номер байта в плоском адресном пространстве. Хотя, если адресное пространство плоское, то скорее всего там и правда будет плоский номер байта.

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

Кстати, увы но тут он прав, я пытался так делать (не для syscall а для вставки прекомпилированного блоба в код), как заставить gcc сгенерить рабочий результат из такого - не разобрался. Проще оказалось его асмом командами .byte закодить - они уже в кодовой секции оказались.

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

Ты прям точно описал суть С89. Осталось только принять это. А все остальные «С-стандарты» это дополнения к этому документу.

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

как заставить gcc сгенерить рабочий результат из такого - не разобрался.

Переменная должна быть глобальная или static, тогда она попадает в .data или .rodata, линкеру потом сказать что .(ro)data в исполняемый сегмент надо. Можно attribute((section(«.text»))) использовать. На некоторых архитектурах static const искаропки в .text попадает. Можно вообще в отдельную специальную секцию поместить и линкеру сказать что в исполняемый сегмент её надо. В общем, куча вариантов.

Stanson ★★★★★
()
Ответ на: комментарий от shkolnick-kun

Это какое-то извращение. Я стараюсь suckless придерживаться по мере возможности.

Вроде смотришь, нормальные мужики:

Use tabs for indentation and spaces for alignment.

но потом замечаешь

  • Do not mix declarations and code.
  • Do not use for loop initial declarations.

что всё-таки поехавшие.

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

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

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

Do not mix declarations and code.
Do not use for loop initial declarations.
что всё-таки поехавшие.

А по-моему прекрасные правила (эти два - про то что не надо объявлять переменные где попало), сам их придерживаюсь (то что они ещё где-то сформулированы - не знал).

Вроде смотришь, нормальные мужики:
Use tabs for indentation and spaces for alignment.

А тут наоборот: с некоторых пор решил обходиться без табов вообще.

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

Вроде смотришь, нормальные мужики: Use tabs for indentation and spaces for alignment.

Мне кажется это плохая идея: табы не везде 4 пробела, а мешать их так вообще ужас, как мне кажется. Но я придерживаюсь Barr Group’s Embedded C Coding Standard (не везде согласен, но много где придерживаюсь), поэтому все это вкусовщина, такая же как и где ставить {: на отдельной строке или на той же где и объявление какого то блока.

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

Мне кажется это плохая идея: табы не везде 4 пробела, а мешать их так вообще ужас, как мне кажется.

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

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

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

Будут, отступы по 8 пробелов это ужас. Ну а некоторым (например мне) и по 4 не нравятся. А комбинировать пробелы для маленьких отступов и табы для больших - создадут проблемы с разными размерами.

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

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

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

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

Вроде смотришь, нормальные мужики: Use tabs for indentation and spaces for alignment.

Мне кажется это плохая идея: табы не везде 4 пробела, а мешать их так вообще ужас, как мне кажется.

Ты просто не умеешь их готовить.

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

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

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