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

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

И правда, с -O0 есть в gcc 10.

Ну это не «превращение похожего кода в вызов», это у gcc такая реализация инициализации переменных. Спорная, да.

Но зачем ты -O3 вписал в команду непонятно.

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

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

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

в этом что-ли проблема? отключите нужные оптимизации, если это вас так парит… на моей памяти даже в с++ gcc таких проблемы не было, когда libc была вообще своя.

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

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

Ну это не «превращение похожего кода в вызов», это у gcc такая реализация инициализации переменных. Спорная, да.

Это превращение похожего кода в вызов. Буквально:

           The compiler may generate calls to "memcmp", "memset", "memcpy" and
           "memmove".  These entries are usually resolved by entries in libc.
           These entry points should be supplied through some other mechanism
           when this option is specified.
gaylord
()
Последнее исправление: gaylord (всего исправлений: 1)
Ответ на: комментарий от firkax

Затем, что это цитата из багтрекера. Научись читать, пожалуйста.

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

Где тут про превращение кода?

Если бы он тебе for(i=0; i<10; i++) x[i] = 0; заменил на memset то да, он превратил твой цикл в вызов функции. А тут никаких алгоритмов не было в оригинале, было объявление переменной со статическим инициализатором.

Ещё gcc для некоторых арифметических операций например с int128 (или с int64 на 32-битной архитектуре) тоже генерирует вызовы функций - у него такая реализация оператора умножения (или не помню какого).

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

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

Если бы он тебе for(i=0; i<10; i++) x[i] = 0; заменил на memset то да, он превратил твой цикл в вызов функции. А тут никаких алгоритмов не было в оригинале, было объявление переменной со статическим инициализатором.

Ты понимаешь что наличие вызова memcpy() это проблема для -nostdlib? Потому что стандартной библиотеки просто нет. И не факт что ты хочешь линковать libgcc.a.

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

Перечитай опции компилятора ещё раз. Читай, пока не поймешь.

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

если gcc лично тебе тебе что-то там заменил, подай на него в суд и выиграй дело.

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

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

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

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

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

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

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

Вы серьёзно считаете это проблемой GCC? Нет, это просто недостаток вашего понимания того, как работает современный компилятор. Он увидел очевидный шаблон копирования памяти и, разумеется, заменил его на memcpy. Это базовая трансформация, которая улучшает производительность и читается как знак того, что ваш код слишком тривиален, чтобы не быть оптимизированным.

Если вы компилируете без libc — сообщите об этом компилятору. Используйте -ffreestanding, -fno-builtin, -nostdlib, и он не будет подставлять внешние символы. Не делаете этого — не удивляйтесь, что он предполагает стандартную среду исполнения. Это не баг, это ваше недоопределённое окружение.

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

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

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

Вы серьёзно считаете это проблемой GCC? Нет, это просто недостаток вашего понимания того, как работает современный компилятор. Он увидел очевидный шаблон копирования памяти и, разумеется, заменил его на memcpy. Это базовая трансформация, которая улучшает производительность и читается как знак того, что ваш код слишком тривиален, чтобы не быть оптимизированным.

Ты не смог прочитать опции, в которых написано «у меня нет libc и я не хочу чтобы ты генерил мне memcpy».

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

Ты читаешь сообщения до конца перед тем как на них отвечать?

Конечно, а ты?

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

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

Похоже ты просто не писала ничего серьезного на C. Так, байтики копировала. До сегодняшего дня даже не знала что компилятор заменяет код на memcpy() и memset(). Кажется, что ты не можешь называться сишником.

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

если gcc лично тебе тебе что-то там заменил, подай на него в суд и выиграй дело.

Что за бред ты несешь? Разговор был о неявном поведении в C и его полно.

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

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

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

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

конечно. а что, есть проблемы?

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

и всё это НИКАК не относится к «неявному поведению в Си». не надо создавать видимость какой-то проблемы из ничего.

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

ещё раз, для тех, до кого долго доходит:

баг gcc - это не «неявное поведение в Си». точка.

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

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

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

В си нет ни одной конструкции сложной семантики… навроде эксепшенов, множественного наследования, async/await, сборки мусора, счета ссылок и проч. высокоуровневой чепухи. И это правда.

А то что он извращается на оптимизациях… так они для того и оптимизации. поскольку семантика сишечки(идущая от древних архитектур) далека от железа всяких там современных суперскалярных процов.

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

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

баг gcc - это не «неявное поведение в Си». точка.

А что такое неявное поведение? Потому что особенности работы GC в Go тогда тоже не неявное поведение и неявного поведения в Go нет.

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

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

Весь стандарт забит неявным поведением из разряда «мы хрен знает что тут будет это компилятор/libc/фаза луны решает». Буквально «implementation-defined behavior». Неявнее некуда.

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

конечно это ужасно. но есть вещи и похуже «темных мест» стандарта си.

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

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

Мой ответ касался общей практики и поведения компилятора по умолчанию, где разработчик не сообщает компилятору явно, что нет libc. В таких случаях замена шаблонов на memcpy — это корректное и ожидаемое поведение. Оптимизатор не обязан «угадывать», что ты вдруг в freestanding-окружении, если ты ему это не сказал.

И да:

1. Оптимизатор при генерации IR (GIMPLE) не всегда учитывает все флаги сразу при матчировании паттернов

2. *ptp = (struct Page_Table_Page){{{0}}}; может компилятором рассматриваться не как «ручной» цикл или memset, а как конструкция, которая требует генерации zero-fill через memcpy/memset по архитектурным или ABI-причинам (например, чтобы сохранить выравнивание, tail padding и т. д.).

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

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

А то что он извращается на оптимизациях… так они для того и оптимизации.

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

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

Но то, что компилятор может дичайше перекроить твою программу для этого - это п-ц какое неявное поведение!

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

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

баг gcc - это не «неявное поведение в Си». точка.

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

более чем 3000 платформ. там тысячи компиляторов.

и ничего подобного не ловила?

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

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

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

насчёт

впрямую в код, но неэффективно

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

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

Мой ответ касался общей практики и поведения компилятора по умолчанию, где разработчик не сообщает компилятору явно, что нет libc. В таких случаях замена шаблонов на memcpy — это корректное и ожидаемое поведение. Оптимизатор не обязан «угадывать», что ты вдруг в freestanding-окружении, если ты ему это не сказал.

С этим вообще никто не спорит.

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

Начинается. Язык не существует в вакууме, у него есть реализации. Сишные реализации – ад и израиль.

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

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

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

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

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

Серьезно? Ты вот это приводишь как достижение за 30 лет работы? Код стал на треть быстрее?

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

я переписывал обширный код на плюсах, в плюсы же, под тем же gcc, и он работал быстрее в двести! примерно раз.

и все потому, что в исходном коде особо увлекались смартпоинтерами, new/delete там, где можно обьект держать на стеке и все такое.

причем сам алгоритм не менялся.

вообще си не быстрей с++. при правильном подходе у них скорость одинакова, но на си++ писать проще.

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

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

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

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

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

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

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

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

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

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

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

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

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

вот нет. в Си есть набор простых (очень простых!) служебных слов. и он небольшой. в нём нет никакой развесистой клюквы

Ты стандарт-то видела? Нет там развесистой клюквы, ага. Список неопределённого поведения на полтора десятка страниц только.

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

А пруфов твоей кваликации у нас нет, твоего кода найти не удалось.

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

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

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

так я и не копаюсь в логах багрепортов gcc.

Значит ты не делаешь ничего интересного.

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

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

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

конечно видела. я его с 90-х годов почитываю, какбэ.

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

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

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

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

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

gaylord
()
Ответ на: комментарий от gaylord
void init_ptp(struct Page_Table_Page*const ptp) {
    *ptp=(struct Page_Table_Page){{{0}}};
}

я канеш не сишник, но что хочет эта функция? Забить весь экземпляр Page_Table_Page по указателю ptp нулями что-ли? чи шо?

вот эта фигулина {{{0}}} это ж структурная константа, а какой у нее размер? что нам говорит стандарт си?

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

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

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

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

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

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