LINUX.ORG.RU

defer в C быть!

 ,


0

9

Привет, ЛОР!

Как я писал три года назад, в стандарт языка Си было предложено добавить выражение defer, выполняющее функцию или блок кода по выходу из области видимости, где оно было объявлено.

На днях данное предложение получило официальный статус и, скорее всего, defer появится в будущем стандарте C2y.

При этом, defer почти наверняка не будет добавлен в C++, так как его использование будет конфликтовать с другими частями этого языка.

Ссылка на пост в блоге автора: https://thephd.dev/c2y-the-defer-technical-specification-its-time-go-go-go

Спецификация: https://thephd.dev/_vendor/future_cxx/technical%20specification/C%20-%20defer/C%20-%20defer%20Technical%20Specification.pdf

лапши из goto станет меньше

rtxtxtrx ★★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)

Дефер в c++ не будет добавлен не потому, что он конфликтует с другими частями, а потому что это дикий костыль по сравнению с нормальной реализацией RAII.

Дефер используется в тех язкых, где или вообще нет деструкторов (как в C) или где время жизни объекта невозможно четко проконтролировать из-за GC (как в том же golang, похожую штуку добавили недавно в JS).

anonymous
()

С одной стороны, это хорошо.

С другой - Си от этого особо лучше не станет.

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

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

Я удивлён, что так быстро. Всего 3 года от первого предложения до готовой спеки прошло. #embed дрочили 6 лет прежде чем добавить в стандарт, хотя там реализация просто тривиальна.

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

#embed дрочили 6 лет прежде чем добавить в стандарт, хотя там реализация просто тривиальна.

Теперь еще 10 лет надо подождать, чтобы программисты о нём узнали)

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

Только хотел написать, что как-то долго. А оказывается, это ещё и быстро.

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

Дефер в c++ не будет добавлен не потому, что он конфликтует с другими частями, а потому что это дикий костыль по сравнению с нормальной реализацией RAII.

Вообще, в C++ есть свой defer давно.

Раз: https://www.boost.org/doc/libs/1_85_0/libs/scope/doc/html/index.html

Два: https://en.cppreference.com/w/cpp/experimental/scope_exit

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

Мне понравился коммент в старой ветке xDD

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

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

по сравнению с нормальной реализацией RAII

Глупость пишешь. В цпп из коробки нет удобной альтернативы. Чтобы воспользоваться RAII нужно написать класс. Это оверкилл, если нужно сделать что-то мелкое. Поэтому народ клепает эрзац финализаторы.

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

Чтобы воспользоваться RAII нужно написать класс. Это оверкилл, если нужно сделать что-то мелкое.

Это детали реализации. Вполне удобно делается и для классов. К тому же в C++/Rust есть и дженерики и макросы, по синтаксису оно не получается не сильно сложнее дефереда.

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

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

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

anonymous
()

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

firkax ★★★★★
()

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

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)

А напишите плиз кто-нить в каких кейсах дефер может быть полезен. Единственное что на ум приходит – это избавление от goto error; для очистки ресурсов в множестве мест блока кода. Какие еще кейсы?

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

Вообще, в C++ есть свой defer давно.

это просто defer-образная(вырвиглазная) пришлепка над raii. там все равно рисуется некий класс через шаблон.

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

Boost == C++

Починил. Boost уже давно работает как экспериментальное расширения стандартной библиотеки и многие вещи из него переносятся в STL практически как есть.

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

это просто defer-образная(вырвиглазная) пришлепка над raii. там все равно рисуется некий класс через шаблон.

Да ваще насрать 10 раз. Выглядит как defer, работает как defer, значит это defer.

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

как оно вообще будет взаимодействовать с goto?

если обойти defer используя goto, то ничего не отложится. с одной стороны это выглядит как «ошибка», в другой - вполне можно программировать и так. типа хочу чтобы defer был или не был в зависимости от ситуации.

недостаток defer в том, что он никак не связан лексически и даже логически с тем кодом, который собираются терминировать. и вполне можно сломать уже имеющийся defer, меняя код. то есть нужно особо внимательно менять код. и смотреть есть ли defer’ы(их может быть много в одном блоке) и что они там делают.

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

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

Всё так. Автор этого и многих других добавлений в сишных стандарт – фурри и понитрах (и скорее всего гей и/или трансформер). Вот такие люди нынче пилят стандарт твоего любимого языка.

А ещё он любит Rust.

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

как оно вообще будет взаимодействовать с goto?

Сходи по ссылке и почитай. Там всё написано.

недостаток defer в том, что он никак не связан лексически и даже логически с тем кодом, который собираются терминировать. и вполне можно сломать уже имеющийся defer, меняя код. то есть нужно особо внимательно менять код. и смотреть есть ли defer’ы(их может быть много в одном блоке) и что они там делают.

Виктор Степаныч, вы что ли?

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

Виктор Степаныч, вы что ли?

бери выше! я егор моисеич!

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

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

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

но с defer такое не прокатит, придется ручками в этих defer закрывать файлы,… и это кончится тем, что однажды это сделать забудут. и начнется страшный, демонический ор о небезопасности си в пользу рустоперделок.

а в плюшечке - все чисто. там raii, как доктор прописал. и можно с гордостью дать пинком под зад расту вашему.

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

Вообще, странный персонаж. Достаточно посмотреть на его мастодроч https://pony.social/@thephd. Любит себя называть ThePhD, хотя, насколько мне известно, никакой степени у него нет.

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

Я уже 10 лет как использую что-то вродеэтого, и не парюсь.

Это практически scope guard из буста по ссылке выше, только костыльный. Не пиши костыли, возьми Boost.

Вообще, странный персонаж. Достаточно посмотреть на его мастодроч https://pony.social/@thephd. Любит себя называть ThePhD, хотя, насколько мне известно, никакой степени у него нет.

Вообще насрать, что у него там есть. Чувак в одно рыло на мощи чистого аутизма вдалбливает в Сишечку действительно нужные вещи, а не очередное UB в realloc().

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

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

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

Не пиши костыли, возьми Boost.

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

вообще толковейший совет - вместо десятка своих «костыльных» строчек возьми 11 хидеров «правильной реализации». Вбыб бы за такое.

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

В бусте как раз костыльный. Там надо поддерживать C++03, а мне не надо. Эта бустовская библиотека появилась в 2006 году, но я ещё не разу не видел, чтобы хоть кто-то её использовал. Не секрет, что в бусте половина библиотек вообще никому не нужна. Вот эта - одна из них.

До сишечки, он пытался что-то вдалбливать в С++ и даже в хруст. Из C++ его выперли, и даже для хруста он оказался сильно скандальным.

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

Это буквально вся суть defer: убрать паровоз

error_free_this:
…
error_free_that:
…
error_free_eh:
…
error:

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

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

Ну возможно стоило не defer, а attribute cleanup в стандарт тащить. Это почти полноценный деструктор.

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

У raii в c++ и помимо необходимости создавать класс куча проблем. Максимально убогая реализация перемещения, раздувающие деструкторами и всякими стражами код shared_ptr, без которого raii становится неюзабельным.

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

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

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

Глупость пишешь. В цпп из коробки нет удобной альтернативы. Чтобы воспользоваться RAII нужно написать класс. Это оверкилл, если нужно сделать что-то мелкое. Поэтому народ клепает эрзац финализаторы.

С точки зрения стандарта С++ defer — это просто незначительный синтаксический сахар поверх RAII, потому в стандарте не нужно. Кроме того, его нужность сильно зависит от стиля программирования. В махровом ООП код устроен так, что необходимости создания дополнительного класса для финализации просто нет, потому что все ресурсы управляются внутри основных классов.

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

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

Строго говоря, это имеет мало отношения к компилируемости языка.

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

Проблема в том, что defer вызывается всегда, а не только в случае ошибки.

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

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

А в Zig помимо defer есть ещё errdefer, код которого выполняется только в том случае, если выход из области видимости происходит из-за ошибки. К сожалению, в сишке такую же штуку заполнить будет сложно, т.к. там нет чётко определённого понятия ошибки.

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

Не секрет, что в бусте половина библиотек вообще никому не нужна. Вот эта - одна из них.

Настолько не нужна, что её уже в STL скопировали и она будет частью следующего стандарта.

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

Из комитета C++ недавно выперли чувака за то, что он употребил слово «question». Якобы, это у кого-то вызвало ассоциации с холокостом. Там настолько поехавшие шизофреники, что на их фоне даже аутист-понитрах выглядит адекватным.

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

Да, в сишке придется выдумывать специальную метку «если мы попали сюда, начинай разворачивать errdefer». Но это все уже мертвому припарки, проще Rust или Zig взять.

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

С другой стороны, errdefer на практике нужен гораздо реже, чем defer, так что при необходимости его можно костылить руками через defer+флаг, а костылить каждый раз руками рутинные штуки (в которых легко допустить ошибку и накосячить) для сишников — дело привычное, они даже этим гордятся!

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

комитетчики делают что-то полезное

Вангую, что получится как всегда.

no-such-file ★★★★★
()
Ответ на: комментарий от gaylord

Да не, наверно будут делать что-то типа такого

int my_fun(...) {
  bool got_error = false;

  /* poor man's errdefer */
  defer {
    if (got_error) {
      do_error_cleanup()
    }
  }

  /* ... */

  if (something_went_wrong()) {
    got_error = true;

    return -1;
  }

  /* ... */
}
theNamelessOne ★★★★★
()
Ответ на: комментарий от mittorn

Искренне наслаждаюсь попоболью от Boost у фанатов истенного C++. Хотя, казалось бы, такую срань как C++ бустом уже точно не испортить.

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

Проще взять кресты

Вообще нет. Я учил людей крестам и Rust, и в случае второго это куда более простой процесс.

gaylord
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)