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

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

Добавил в начало, ничего не поменялось, всё так же ошибка. К нему и мана нет.

Это ещё может быть связано с тем, что у функции memset_s четыре аргумента, а ты в своём примере вызываешь её с тремя.

А чтобы действительно проверить, что в gcc эта функция есть, надо проверить соответствующий дефайн __STDC_LIB_EXT1__:

#ifndef __STDC_LIB_EXT1__
#error "memset_s not supported"
#endif
theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Потому что наверняка есть куча кода, которая работает потому что memset() выкидывается. Ну я просто жопой чую. Если где-то в коде кто-то мог обосраться, то это просто 100% случится. Особенно если это код на C.

))

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

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

тушка которой может быть в другой библиотеке или вообще хз где

Неважно, где она есть. Инлайнится она или линкуется, пока реализация корректна – ее использование не будет выкидываться.

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

Это не особая магия. Стандарт запрещает убирать или изменять volatile операции. Хотя explicit_bzero обычно реализуется на gcc-специфичном __asm__ (поддерживаемом, тем не менее, и clang’ом), аналогичного поведения достигает OPENSSL_cleanse с помощью полностью удовлетворяющего стандарту кода.

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

Дурное здесь это использование goto.

В явном виде. С понятной механикой и целями. Это дурное. А на тащить неявных вызовов при выходе из области памяти, это, значит, не дурное. Готу к месту - самое то!

pihter ★★★★★
()

ВНОСИТЕ ЦАРЯ!

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

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

Стандарт говорит что доступ к volatile-объектам относится к observable behavior, которое реализация должна воспроизводить.

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

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

Ориентироваться на то чтоб сохранить работоспособность неправильно-написанного кода – ну так себе идея

Тем не менее, большая часть юзерспейсного кода в лялексе, а так же собственно само ведро, без -fno-strict-aliasing работать не будут.

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

А если взять volatile-указатель

Тут, естественно, имеется в виду указатель на volatile-qualified тип, а не то, что сам тип указателя volatile-qualified.

anonymous
()

… лямбды в стиле C++

Понятно …

C++ из Си сделают ...

Модно, молодежно, … и все макаки ОДОБРЯТ! …

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

Тем не менее, большая часть юзерспейсного кода в лялексе, а так же собственно само ведро, без -fno-strict-aliasing работать не будут.

И? Это ровно обратная ситуация - код ломается из-за чрезмерно агрессивного оптимизатора. strict aliasing это более агрессивное действие чем выкидывание memset, оно в отличие от выкинутого memset-а меняет логику работы функционального аспекта программы.

Вот если бы они работали только с включённым strict aliasing - это был бы явно дефектный код, аналогично тому как если что-то рабоотает только с выкинутым memset-ом.

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

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

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

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

Настрочил много букв и не стал публиковать.
Надеюсь Си не скоро УГРОБЯТ! …

anonymous
()

Вообще не понятно, что так все переполошились. Ну добавят и добавят. Никто же не заставляет пользоваться.

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

«Общим местом»… Нужником что ли?

Понял его пост так

ОТХОЖИМ МЕСТОМ ...
anonymous
()
Ответ на: комментарий от firkax

В стандарте (в данном случае им является man-страница из openbsd, откуда родом эта функция) написано что explicit_bzero не может быть выкинута.

man-страница из openbsd является стандартом C не более, чем им является документация из Windows. Другими словами, вообще никак не является.

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

Я спрашивал уже, ты так и не ответил - ответь всё-таки, ты пишешь на Си как на основном языке или нет?

Каэш! Кто тут на нём не пишет?

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

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

Ъ? В пропозале так и предлагается.

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

В пропозале так и предлагается

selffix: не совсем так, но очень примитивно - вся динамика втиснута в один счетчик.

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

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

seiken ★★★★★
()

В стандарт C предложено внести лямбды и defer из golang

Нас не догонят!  
Нас не догонят!  ...
anonymous
()
Ответ на: комментарий от hateyoufeel

man-страница из openbsd является стандартом C не более, чем им является документация из Windows. Другими словами, вообще никак не является.

Причём тут стандарт С? Конкретно эта man-страница является стандартом на функцию explicit_bzero - на правах первоисточника.

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

setjmp/longjmp уже есть

Это не функционал языка, а библиотечный функции. Их можно использовать или сделать аналогичные в Паскале, Обероне, Go, D, Rust и т.п..

Также вопрос что будет с предложенным defer после longjmp.

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

Причём тут стандарт С?

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

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

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

defer очевидно не будет выполнен. Как и C++ деструкторы для локальных переменных.

А ещё в msvc есть __try __except давным давно (и я таки не могу им отказать в признании того что это - Си), только они не управляемые исключения ловят а сегфолты. Впрочем никто не мешает *(int*)0 = 0; отправить.

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

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

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

Вот и еще одно доказательство того, какой Шома пидарас! Ну какой нормальный модератор банил бы по IP? Ведь можно забанить очень приличное количество пользователей (а уж про анонимусов вообще молчу).

А этой антироссийской твари похуй. Вот же пиздоблядский выродок! Как его только мать вынашивала?

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

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

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

Си это не что-то сферическое в вакууме.

Да, я в курсе. Я ещё на первой странице написал, что существует три разных C.

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

Компилирует эти библиотечные функции кто? Операционная система? Спецификация? Инопланетяне?

мы имеем дело всего лишь с возникающими иногда багами.

иногда

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

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

Компилирует эти библиотечные функции кто?

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

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

Думаю всё же это подавляющее меньшинство багов.

Интересно, а куда ты отнесёшь баг, связанный с чтением за границей массива? Ну, то есть например у тебя есть char a[15], ты читаешь, условно, (*(long*)(a+14)) & 0xFF. Такая конструкция где-то будет работать стабильно, а где-то - время от времени крашиться. Речь про little endian везде.

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

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

На чём «они» написаны, не то чтобы важно. Оптимизация происходит в месте вызова.

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

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

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

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

Он и не будет. Он просто выкинет вызов функции.

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

Вагоны багов вызваны тем, что программисты и разработчики компиляторов по-разному понимают стандарт

И при всем этом ничего лучше за 50 лет так и не сделали.

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

И при всем этом ничего лучше за 50 лет так и не сделали.

Ты ещё скажи, что за 50 лет нормальный тип для строк никто не придумал до сих пор.

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

С чего это ему выкидывать вызов функции? А может она печатает содержимое буфера на экран? ИИ, который интерпретирует название функции и догадывается о том, что она может делать, там нет. Это для memset/bzero там спец. логика сделана, для остальных такое может случиться только если компилятор непосредственно видит её исходник.

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

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

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

Как и C++ деструкторы для локальных переменных.

Бывают реализации longjmp которые внутри вызывают ForcedUnwind так что деструкторы вызываются.

только они не управляемые исключения ловят а сегфолты

В Windows SEH управляемые исключения и сигналы обрабатываются одинаково.

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

Ты ещё скажи, что за 50 лет нормальный тип для строк никто не придумал до сих пор.

Пример нормальной реализации строк будет?

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

switch не вызывает никакие функции сравнения

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

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

Пример нормальной реализации строк будет?

Погоди, ты сейчас реально будешь напирать на то, что нормальных строк и правда нет? Ох лол!

Ну начни с Паскаля, например. Даже там дела со строками лучше чем в C.

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

Ну начни с Паскаля, например. Даже там дела со строками лучше чем в C.

Нет, не лучше. Там другая реализация, в чём-то она удобнее, в чём-то наоборот хуже, и существенно.

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