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

Лучше бы поддержкой юникода из коробки озаботились (хотя бы буковки или кодепоинты подсчитывать и нормализовывать). Больше толку было бы.

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

Ты все свои программы собираешь с O0?

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

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

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

Мне даже стало интересно, не связано ли это с как-то с ковидобесием и прочей фигнёй. :)

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

Тут можно ещё много по кругу писать, но пожалуй не буду. Суть аргументов сводится к одному: switch это тривиальный выбор варианта для перечислимого типа. Введение дополнительной логики тут неуместно, но можно сделать с другим названием.

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

Как я уже неоднократно писал, gcc это и есть стандарт. То, что некий комитет публикует своё альтернативное видение - ну, пусть тоже стандарт, но менее важный. Хотя авторы clanga конечно попортили ситуацию своей дубоголовостью.

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

конкурентноспособным на рынке.

Язык не может участвовать в конкуренции сам по себе. Участвуют выгодоприобретатели, а их продукт - приманка. Какой выгодоприобретатель использует Си как приманку для окучивания аудитории? Нет такого. Язык придумали для собственного удобства и он до сих пор таковым остаётся.

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

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

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

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

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

приближена к железу

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

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

Там есть какой-то wchar.h, хотя я им не пользовался никогда.

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

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

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

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

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

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

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

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

а вот case для строк частенько был бы кстати.

строка в си - не тип, а просто представление текстовых данных. сама переменная будет типа - char[n]. но char[n] не обязательно содержит нуль терминированную строку.

как тогда компилировать switch (array_of_char)… если там нет гарантий, что это нуль терминированная строка?

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

Еще бы полноценные макросы как в лиспе.

Чем тебе define не полноценный?

У тебя зияющий пробел в знаниях, если ты это всерьез.

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

Зачем нужны два языка, в которые добавляют одни и те же фичи, только с разницей в 10 лет? Я не понимаю.

+100500

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

Иди ассемблер понюхай, а потом про адреса что-то кукарекай.

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

Фишка сишечки в том, что в ней нет никаких скрытых механизмов. Прямая трансляция program flow в instruction flow. Если начать туда напихивать всякое, то внезапно получится C++, который уже есть.

золотые слова

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

Язык не может участвовать в конкуренции сам по себе.

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

Участвуют выгодоприобретатели, а их продукт - приманка. Какой выгодоприобретатель использует Си как приманку для окучивания аудитории? Нет такого. Язык придумали для собственного удобства и он до сих пор таковым остаётся.

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

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

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

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

Так делают, если есть несколько return в функции и перед выходом нужно освободить память или другие ресурсы. Чтобы перед каждым вызовом return не вставлять одинаковый код освобождения, его выносят в конец функции под метку cleanup (например). И вместо return делают goto cleanup.

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

А в языке C указатели – это не целые и не числа. Даже не знаю, почему до тебя это не доходит никак.

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

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

Строковые константы вполне может обрабатывать компилятор на этапе компиляции и соответственно использовать strcmp, например, для сравнения.

Но это не больше чем синтаксический сахар, просто чтобы вместо лесенок с strcmp и скобкотой писать несколько более удобочитаемые case, только и всего.

Ну задефайни себе неявное использование strcmp для строк и изобрети какой-нибудь STR_CASE… просто все кто так делают через время выясняют что и без этого норм )

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

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

Хахахахаха! Охохохохох! Уахахахахахах! Сишечка приближена к железу! Вот это умора!

К какому железу она приближена? К PDP-11?

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

Чем тебе define не полноценный?

однопроходный :( нельзя задефайнить дефайн

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

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

Учитывая, что 99% софта собирается с оптимизациями, что же это выходит? Что это всё результат работы оптимизатора, а процессоры не нужны?

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

А кому нам верить? Тебе что ли? Стандарт C по-солиднее будет!

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

Да, к PDP-11. Сишечка это макроассемблер PDP-11, не больше и не меньше, в этом её достоинства и недостатки.

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

Вот здесь вызов memset() будет почти наверняка выкинут, потому что «нет побочных эффектов». Ну, кроме потенциальной утечки ключа, разве что. Но с каких пор господ волнует безопасность?

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

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

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

Этот ключик может таких лулзов добавить, потом баги чинить офигеешь.

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

In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

Секция 5.1.2.3, пункт 4 (https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf).

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

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

Наверное, было бы классно действительно выкинуть существующий стандарт на помойку и сделать новый, который будет описывать именно существующий язык. И заодно убрать оттуда всё UB и сделать его DB. Потому что оптимизации, от которых все выигрывали 40 лет назад, сейчас уже довольно бесполезны и наносят больше вреда чем пользы. Но увы и ах, этого не случится, и программисты на C так и будут отстреливать себе яйца из пулемёта.

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

Чет от действий этого комитета иногда икается.

Короче, старый механизм никуда не денется? Совместимость останется?

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

Тут понимаешь, все прямо как с GTK. Пусть делают что угодно, лишь бы совместимость не ломали. Кому надо модно-стильно-молодежно пусть дописывает -C99/23/etc., но мне оставьте возможность писать в стиле -С89 и спокойно комилить это. А дальше хоть в гузло долбитесь, меня это касаться не должно.

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

А тебя вернуть обратно в дурку.

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

Решит частичную «проблему» и породит новые. Вот весело то будет искать двойные освобождения. Работа с памятью всегда ручная за исключением стековой если люди забывают free вызвать в обработке то они и defer { free(p); забудут. Бесполезная херота к тому же неявный вызов + к отладочному раю. Ну пускай добавляют один хрен для 99% случаев нужен только с99, а уже выше пофиг как то, хотя я и про генерики так говорил, но в своих наколенных поделках порою очень даже удобно. Только вот опять же до первых проблем, а то вместо поиска чего не так в 1 функции будешь искать в 10ти ибо они все под генериком спрятаны ну как пример. В общем добавят или нет не особо то и важно так как это всё ещё одни пути решения того что и так уже решается и всегда решалось.

скоро в C больше не будет нужно использовать goto вообще нигде

пфффф =)

LINUX-ORG-RU ★★★★★
()

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

Не понял с чего такой вывод. Очень часто goto используют для чистки ресурсов при выходе по ошибке, а при отсутствии оной — возвращают указатель вызывающему, ничего не чистя. Этот defer позволяет отмену? Вроде как нет.

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

Это именно проблема языка, на которую все положили огромный болт.

В стандарт внесли предложение по поводу функции memset_explicit которая как memset, только оптимизатор чтобы её не удалял :)

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2897.htm

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

Или предполагается писать defer { if (rc) free(...); }? Ну тогда может и ок.

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

Зачем нужны два языка, в которые добавляют одни и те же фичи, только с разницей в 10 лет? Я не понимаю.

Золотые слова!

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

Кстати, мне немного стыдно, но я не понимаю, почему при сборке gcc результат false.

Потому что в стандарте так написано.

6.5.9 Equality operators, пункт 7

Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space

Здесь видно что это адреса указывают на разные объекты, так что оптимизатор сразу заменяет на false, не сравнивая значения указателей.

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.