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

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

С чего бы вдруг? Ну не повезло, побился рейд или диск лажу вернул. Может nfs затупил или проблемы в overlayfs.

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

Няш, а почему ты не хочешь проверять вызов close? Ты недооцениваешь опасность, чтоли? О_о Скажи нам, в чем разница-то?

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

Логи это всегда best effort. Обосраться в стек — баг. Понимаешь разницу?

теоретически ты прав, но практически – это ж шизофрения. :-D

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

Потому что для этого у меня есть ты, анон! Вот буду программировать на C, посажу тебя к себе на коленки, и ты будешь каждый раз, когда я печатаю close(), на отдельной клавиатуре набирать код для проверки. А я буду в это время перебирать пальцами твои шелковистые волосы и поправлять твоё платье.

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

теоретически ты прав, но практически – это ж шизофрения. :-D

Порча стека из-за такой ерунды – шизофрения? Согласен.

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

Потому что для этого у меня есть ты, анон! Вот буду программировать на C, посажу тебя к себе на коленки, и ты будешь каждый раз, когда я печатаю close(), на отдельной клавиатуре набирать код для проверки. А я буду в это время перебирать пальцами твои шелковистые волосы и поправлять твоё платье.

это будет нашей тайной (^‿^) и я никому-никому не расскажу что ты обосрался.

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

Какой сигнал заставит read вернуть -1?

Любой, не завершающий программу. Внезапно, правда?

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

Любой лол!

man 2 read

On error, -1 is returned, and errno is set to indicate the error.

In this case, it is left unspecified whether the file position (if any) changes.

EINTR The call was interrupted by a signal before any data was read; see signal(7).

Кстати, всё ещё банальнее. Если там пусть ведёт не к файлу, а к директории, то read() сфейлит с -1 и EISDIR в errno :D

Ларчик очень просто открывался! Подаёшь на вход директорию вместо файла, код @Stanson срёт в штаны^Wстек.

$ cat dir.c
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
  int ret, fd;
  char buf[256] = { 0 };
  
  fd = open("/", O_RDONLY);
  if(fd < 0) {
    printf("open failed: %s\n", strerror(errno));
    return 0;
  }

  ret = read(fd, buf, sizeof(buf));
  if(ret < 0) {
    printf("read failed: %s\n", strerror(errno));
  }
  close(fd);

  return 0;
}
$ gcc dir.c -o dir && ./dir
read failed: Is a directory

Проверки, что он открывает именно файл а не директорию там тоже нет. Так что вот он, 100% просёр мимо буфера прямо в штаны. Даже без экзотических условий.

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

ты даже не понимаешь в чем твоя шизофрения, и это логично, на то она и шизофрения.

Ну вот так мама воспитала. Говорила: не сри себе в стек! Я и не сру. А @Stanson’у видимо не говорила :(

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

няш, я тя узнал, харош с под анонима срать))

Скажи @Stanson’у чтобы он в стек срать перестал.

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

Какой же классный наброс получился

Да ну, уныло уже давно. Стандартных ход мыслей, уже и не смешно.

  • Сишники сила, жаба могила!

  • А вот у вас тут порча памяти сходу…

  • И чо?! Это не по-настоящему, а у вас так вообще негров линчуют.

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

Так что вот он, 100% просёр мимо буфера прямо в штаны.

Разговор о штанах длился и длился, и я уже забыл, что именно этим доказывается. Так С говно или нет?

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

Разговор о штанах длился и длился, и я уже забыл, что именно этим доказывается. Так С говно или нет?

C – штаны.

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

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

Что @Stanson не может на C писать. Тащемта и всё.

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

Мелковата дискуссия. Хотя и весело.

Ты не понимаешь рецепт. Смотри:

  1. Вбрасываешь немного про C
  2. Выискиваешь сишника, который затирает, что C рулет и только ламеры его не осилили
  3. Ищешь код этого сишника
  4. Находишь там просранные буферы, use after free, разыменование NULL, UB и прочие сишные радости. Они там будут, я гарантирую!
  5. Наслаждаешься нелепыми отмазами очередного говнокодера
  6. ???
  7. PROFIT

Я, кстати, всё мечтаю на код Железо_Жука посмотреть. Но в публичном доступе вроде не видел.

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

Но ведь С все равно рулет, с этим-то как быть?

И педалет, конечно. За исправление поделок говнокодеров, которые даже в буфер попасть не могут как Stanson, классные деньги платят. Как и за миграцию софта с C на что-то более адекватное.

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

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

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

Понятия не имею. Мне Rust вместо C в большинстве случаев вполне подходит, кроме как когда нужно активно с сишным кодом общаться (или с плюсовым, как в случае с Qt). Тебе может не понравиться. Решай сам, тебе же говнокодить.

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

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

thesis ★★★★★
()

Пролистал первые 2-3 страницы, и про это уже сказали, но всё равно повторю.

Я тут тебе немного покушать принёс.

Indeed.

в этот стандарт предложено добавить механизм defer

На плюсах реализуется в 5 строк как обычный класс.

Си не нужен. У меня всё.

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

можно move добавить в конструкторе, одной копией меньше будет.

Хотя в std::function есть небольшой буфер как в std::string, который позволяет не выделять память если список захвата не очень большой, но лучше всё равно move делать…

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

Гуглил эту тему когда писал, и рекомендации были типа «copy if unsure». Ну я почесал репу и подумал – «ну как хотите, copy так copy». Сенькс, значит это не я дурак.

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

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

Хотя если честно я не вполне догоняю: я думал что там всегда всё на стек падает. Разве что если какой-нибудь типа vector по значению захватывается, но тут уж вряд ли компилятор сможет copy constructor вектора выкинуть (разве что в случае const access с учётом scope).

UPD. Т.е. std::function внутри – это структура-функтор, с полями-захваченными ссылками и значениями, и одним методом. Если function создаётся без new – это значит структура создаётся без new.

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

А теперь наведи мыша на ссылку на источник [18] и посмотри на автора и даты.

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

С вами ещё проще

  1. Видишь очередной маркетинг очередной ненужной хипстерской хероты
  2. Берёшь любого адепта срущего рекламой ненужной хипстерской хероты
  3. Ищешь код этого адепта или хотя бы что-то полезное написанное хоть кем-то на этой хипстерской хероте
  4. Не находишь.

Ну смешно же. :) Какому-нибудь расту - уже больше 10 лет. За это время на нём не написано вообще ничего полезного. Совсем. Абсолютно ничего. При всём беспардонном маркетинге.

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

Я ж говорю - return, а там трава не расти. Зачем, почему, для чего, что будет дальше - совершенно насрать.

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

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

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

Т.е. std::function внутри – это структура-функтор, с полями-захваченными ссылками и значениями, и одним методом. Если function создаётся без new – это значит структура создаётся без new.

std::function это структура, которая стирает тип конкретной функции, лямбды или функционального объекта, и хранит в себе

  1. конструктор копирования переданного функционального объекта
  2. деструктор переданного функционального объекта
  3. оператор вызова переданного функционального объекта
  4. указатель на копию объекта переданного в конструкторе
  5. буфер, который используется, чтобы не выделять память из кучи для создания копии объекта, если объект помещается в этот буфер

Вот пример, и в комментариях примерно как std::function выглядит: https://godbolt.org/z/a8x1a6nGP

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

Во, спасибо пребольшое. :)

UPD. Я-то думал, что там структура переменного размера получается, т.е. люто умный компилятор генерирует структуру из типопараметра… Т.е. фактически представлял себе в этом месте полноценное метапрограммирование (ну как полноценное… захардкоженное в компилятор). А там оказывается всё чисто на уровне stdlib рулится. Фигня этот ваш C++. :)

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

Мне Rust вместо C в большинстве случаев вполне подходит,

Это объясняет твое рвение. :)

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

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

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

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

Я, кстати, всё мечтаю на код Железо_Жука посмотреть

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

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