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

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

Нет, с оптимизатором всё в порядке: https://godbolt.org/z/G1bxab1hn и нормально его использовать а не «преодолевать».

Теперь, как и положено, возвращает true

положено возвращать false, не положено менять константу

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

ну просто он 2 УБ напихал, я рассмотрел то которое кастом «отменяет» константность, изменение строкового литерала формально другое УБ

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

У сисколовых обёрток есть ещё один неприятный момент, они возвращают -1, а ошибку при этом пишут в errno.
Возможно лучшим вариантом был бы возврат именно ошибки отдельным аргументом, либо упаковки этой же ошибки в тот же int (как делает настоящий сискол за обёрткой)
В любом случае удобного способа возврата ошибки в си нет, errno больше на костыль похож

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

положено возвращать false, не положено менять константу

а возвращает true. вот так грустно устроена жизнь статических инвариантов в си.

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

почему вообще не си? они сами называют это си и си++.

просто взяли си компилятор и дописали новых правил.

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

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

Этот частный случай как раз прекрасно показывает, почему нельзя полагаться на то или иное поведение в случае UB

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

почему вообще не си? они сами называют это си и си++.

Ты можешь использовать обычный сишный код для CUDA? Как насчёт стандартной библиотеки? Нет, не можешь. Это реально отдельный язык, там даже семантика многих операций другая.

В eDSL для Haskell такая возможность остаётся.

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

я вообще не понимаю откуда в разговорое взялся этот гпу.

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

гпу это специальная погремушка, на которой си в полную силу и не развернуть.

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

я вообще не понимаю откуда в разговорое взялся этот гпу.

@Vic утверждает, что Си близок к железу, потому что на нём можно программировать все современные процессоры. GPU – один из примеров процессора, который программировать на Си нормально нельзя.

гпу это специальная погремушка, на которой си в полную силу и не развернуть.

Это проблемы Си как языка. О чём я тут и пишу.

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

а весь хаскель.

а не весь хаскель

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

Очень много отзывов, но лучше бы по-русски написали, как же всё-таки это работает. Я так понял, что это вариант try {} finally {}

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

try…finally - это перехват эксепшенов, не про это.

А defer это работает как вызов деструктора обьекта при выходе из блока. Просто вместо деструктора вызывается код из блока defer. А когда деферов много они вызываются в порядке обьявления.

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

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

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

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

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

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

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

Но потом почему-то тема перескочила с указателей на константные переменные.

ЗЫ. «Константная переменная», если дословно, звучит как оксюморон.

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

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

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

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

абстрактная машина Си

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

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

В принципе вы пишете все правильно. Типы архитектур, Гарвардская или Фон Неймана, накладывают свой отпечаток на код, который мы пишем, в частности, на языке Си.

Кроме микроконтроллеров AVR ATmega, с раздельными адресными пространствами еще есть микроконтроллеры PIC компании Microchip (PIC16F, PIC12F …). Но такие микроконтроллеры, с раздельным адресным пространством, имеют очень узкий круг применения и маломощные. Им на пятки во всю наступают микроконтроллеры с единым адресным пространством, например, STM32.

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

PS на самом деле многие ARM с единым виртуальным пространством памяти тоже называются гарвардской архитектурой

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

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

Эта, вы снова включили оптимизатор, усилив его уровнем -O1. Верните -O0 и вы получите поведение вашей программы без оптимизатора.

Результат = Program terminated with signal: SIGSEGV

Это срабатывает защита при выполнении кода. Потому, что статическую переменную с директивой const, компилятор попросил операционку поместить в защищенную от записи область ОЗУ. Соответственно, запись в эту область операционка восприняла как нарушение защиты и сняла программу.

А давайте попросим компилятор расположить переменную вне защищенной области, и у нас снова будет true.

https://godbolt.org/z/v4zhnEdhM

Всё же просто.

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

Всё же просто.

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

Может, просто не надо писать такой говнокод, про который прямо в стандарте языка написано что это говнокод? Или это совсем сложно?

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

Не очень профессиональные программисты вечно путают, что, а главное зачем, они хотят сделать константным, и что, реально, а не формально, за этим const скрывается. Это нормально.

ЗЫ. «Константная переменная», если дословно, звучит как оксюморон.

defer Констант в природе не существует 🤣

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

Может, просто не надо писать такой говнокод, про который прямо в стандарте языка написано что это говнокод? Или это совсем сложно?

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

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

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

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

а если канпилятор будет это выбрасывать - то как все это проверять?

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

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

Может, просто не надо писать такой говнокод, про который прямо в стандарте языка написано что это говнокод? Или это совсем сложно?

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

Защита памяти тут не причём, тебе компилятор говна выдаст. @zurg это наглядно продемонстрировал.

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

Сорян, Си как он описан в стандарте для этого не подходит. Вообще, то что Си как-то особенно подходит для системного программирования – какой-то чудовищно всратый мем. В основном системные программисты борются с сишным компилятором, чтобы он им говна не выдавал лопатой, либо вообще делают свои компиляторы (kencc, compcert). Так что, повторюсь, нахрен так жить-то?

а если канпилятор будет это выбрасывать - то как все это проверять?

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

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

UB – это блажь авторов языка Си. К области разработки отношения особого не имеет, потому как приводит к плачевным результатам абсолютно повсеместно.

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

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

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

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

всё так.

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

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

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

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

UB – это блажь авторов языка Си.

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

не, канпилятор тоже хочет на этом поживиться, типа порассуждать всяко и пооптимизоровать что-нить, но труваси ему тут дают по рукам - типа, не лезь не в свое дело.

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

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

Тем временем, в Си являются UB такие вещи как:

В каких из этих случаев всё происходит по воле разработчиков железа, напомни?

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

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

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

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

Тем временем, в Си являются UB такие вещи как:

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

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

Использование значения указателя после вызова free()

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

да я вот буквально этими руками это делал буквально надысь!

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

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

Нет, это не так. Ты путаешь implementation-defined и undefined. В последнем случае, это значит что компилятор просто не даёт гарантий на результат своей работы, и это может как быть ошибкой сборки (незакрытые кавычки), так и говнокодом в бинарнике (см. выше про const, например).

Короче, ты не знаешь Си, как и подобает типичному сишнику.

@alysnix

это детали.

Это не детали, это опровержение твоих слов про то, что UB зависит от железа. Как мы видим, от железа оно не зависит, это просто фантазии авторов говноязычка.

для труваси это рабочий момент.

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

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

UB – это блажь авторов языка Си

скорее стандартизаторов что -бы вендоры уже имевшихся поделий могли утверждать что их изделия(№..) standard compatible

за упоминание kencc +100500

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

бесмсмысленные с точки зрения семантики выражения

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

для этого естессно надо генерить сегфолт нажатием мышки на кнопку. для кого-то это UB(по стандарту). но в данном случае - нормальное положение вещей.

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

Ты путаешь implementation-defined и undefined.

это одно и то же. это означает, что результат неопределён. а определяет его компилятор или нет - это уже детали конкретного компилятора. компилятор может как-то обработать UB, но использовать такие вещи нельзя.

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

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

Ты путаешь implementation-defined и undefined. В последнем случае, это значит что компилятор просто не даёт гарантий на результат своей работы

что я и говорил фразой - «ситуация в которой от компилятора ничто не зависит». ну нет у него методов против кости сапрыкина - труваси со своим сегфолтом. и стандарт это называет - UB

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

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

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

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

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

обработка исключений - это системная вещь. на контроллерах тебе таких услуг могут и не оказать.

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

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

конечно, ты можешь повесить обработчик. но сегфолт - это уже ненормальное состояние процесса.

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

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

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

просто аппаратные прерывания

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

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

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

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

не смотрел я особо на такие контроллеры, просто вангую. и тут вообще речь не о них.

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

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

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

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

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

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

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

но ресурсы могут быть не такие шикарные, как на интелловских процах. и то я вот навскидку не помню, какие, прерывания есть у того же проца x8086, например. наверняка не так много, как у современных процов.

вот наобум контроллер за доллар, и там полный фарш.

https://gd32mcu.com/data/documents/datasheet/GD32F103xx_Datasheet_Rev2.12.pdf

на таком можно и линукс запустить

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

Ты путаешь implementation-defined и undefined.

это одно и то же. это означает

Вообще ни разу. Как минимум, результат implementation-defined кода гарантируется разработчиками компилятора и не меняется в зависимости от флагов сборки.

Повторюсь: ты не знаешь Си. Уволься.

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

а это не Си, детка. это компиляторо-зависимые фичи. а они меняются, как перчатки.

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

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

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