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

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

С другой сторны, учитывая природу C… Зачем там анонимные функции?

Чтобы Stanson отстрелил себе яйца ещё в куче кода :DDD

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

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

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

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

Перестань писать чушь.

Вот здесь вызов memset() будет почти наверняка выкинут

То что memset там может быть выкинут - очевидно, использовать его тут нельзя, на этот случай есть explicit_bzero(). Но тебе со стороны (ты ж не пишешь на Си как на основном языке, верно?) конечно виднее что «тут что-то непонятно».

Это UB. Поздравляю, ты себе яйца отстрелил.

Это не UB, это просто не скомпилируется.

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

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

Это двачую. Тем более что в цепепе вроде работали над embeddable-подмножеством языка, не включающим в себя new/delete (в частности)

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

А чего в new/delete плохого для эмбеддеда? Это просто malloc+constructor и destructor+free считай. Причём програмно заданные в стандартной библиотеке, аналогично тому как malloc задан в libc.

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

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

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

Ну он наверное имеет в виду ту реализацию разнообразных видов конструкторов которые родил с++, которые далеко не просто маллок и фри

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

Во-первых, там если что была вторая ошибка «switch quantity not an integer»

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

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

В мало-мальски разбросанном case у тебя и так будет каскад if-ов. Так что не аргумент вообще.

Это не повод вызывать их неявно из синтаксических конструкций.

К null-terminated строкам и так в сишечке специфическое отношение - как бы просто массив, но в то же время и некий специфический тип данных, обрабатываемый компилятором как минимум в виде строковых констант в тексте программы. Кроме того, многие конструкции языка разворачиваются в вызовы или инлайн builtin’ов, типа присваивания структур и т.п. Так что ничего и ряда вон не будет если добавить ещё switch по null-terminated строкам.

Да и речь вовсе не об этом, а о том, что всякие defer в сишечке гораздо более сомнительны, чем даже case со строковыми константами. Последнее хотя бы можно реализовать прозрачно для program flow.

Stanson ★★★★★
()

Как они собираются поступить с типом лямбд? В С++ тип лямбды может быть преобразован в указатель на функцию только в том случае, если она не захватывает локальных переменных в [], например такое легально

void foo(void (*f)(int)){
    std::cout<<"foo"<<std::endl;
    f(1); // calls lambda which takes an int and returns void
}
int main(){
    foo([](int a){std::cout<<"lambda "<<a<<std::endl;});
}

Как тогда в С будет осуществляться передача лямбды, захватывающей локальные переменные, в качестве параметра функции? Нет ведь ни auto, ни шаблонов. И еще интересно, как внутренне лямбды будут реализованы, в сравнении с С++.

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

То что memset там может быть выкинут - очевидно, использовать его тут нельзя, на этот случай есть explicit_bzero()

Мне очевидно, тебе очевидно, а вот Стансону не очевидно. Он про плохой оптимизатор пишет.

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

Это двачую. Тем более что в цепепе вроде работали над embeddable-подмножеством языка, не включающим в себя new/delete (в частности)

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

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

Но с каких пор господ волнует безопасность?

Господа которые пишут бессмысленный код вряд-ли что-то понимают в безопасности.

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

Господа которые пишут бессмысленный код вряд-ли что-то понимают в безопасности.

Да ты самокритичен! Жаль чувак выше explicit_bzero спалил. А то я бы поинтересовался, как ты подобный код напишешь.

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

Он про плохой оптимизатор пишет.

Я про идиотов, которые языка не знают, но мнение имеют пишу.

В данном случае оптимизатор будет абсолютно прав и всё сделает правильно. Что написал - то и получил.

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

Астрологи объявили месяц клинописи. Количество клинописи в С удвоилось.

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

Тот чувак выше прав, это не UB, твой код тупо не скомилируется. Потому что sizeof(void*) > sizeof(int) на большинстве машин сейчас.

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

Хорошее предложение - ничего больше в язык не принимать. Никогда.

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

А то я бы поинтересовался, как ты подобный код напишешь.

Я подобный код, разумеется, не напишу.

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

Но это не конкуренция

Ок, давайте на пальцах. Раньше сколько было высокоуровневых ЯП для написания всего: от ядра до пользовательской программы? Где-то 2. Теперь добавился 3 у которого есть ещё и преимущество

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

Разработчиками языка, допустим.

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

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

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

Тот чувак выше прав, это не UB, твой код тупо не скомилируется.

tcc компилирует, sdcc компилирует. gcc тоже скомпилирует если заткнуть его верещалку посредством (uintptr_t)ptr

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

Потому что sizeof(void*) > sizeof(int) на большинстве машин сейчас.

А switch не имеет ограничения на размер типа, главное чтобы он целым (integer) был. Адреса - это тоже, совершенно внезапно, целые (integer) числа. Да, тип int представляет целые (integer) числа. Но это совершенно не значит, что все целые (integer) числа обязаны иметь тип int.

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

gcc тоже скомпилирует если заткнуть его верещалку посредством (uintptr_t)ptr

Ну так какую угодно верещалку кому угодно можно заткнуть. Что не спасает от ошибок. Ну и это другой код уже получается.

А switch не имеет ограничения на размер типа. Адреса - это тоже, совершенно внезапно, целые (integer) числа.

Нет. Указатели – это не целые и вообще не числа. Сюрприз!

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

Нет. Указатели – это не целые и вообще не числа. Сюрприз!

Мда. Манямирок любителей абстракций. Расскажи это процессору. :)

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

Мда. Манямирок любителей абстракций.

Манямирок тех, что читал стандарт C. Серьёзно, там указатели идут отдельно от integral types. Попробуй один указатель на другой поделить или умножить, расскажешь что получилось.

Расскажи это процессору. :)

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

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

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

A pointer type may be derived from a function type, an object type, or an incomplete type, called the referenced type.A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called "pointer to T". The construction of a pointer type from a referenced type is called "pointer type derivation"

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

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

И как это может быть связано с тем, что указатель - это целое число?

Лехко! В процах с сегментной моделью памяти (вспомни 8086!) указатель – это два числа. А ещё есть куча других извращений.

Внезапно это всё равно целое число. Не комплексное и не с плавающей точкой и даже не с фиксированной.

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

Не комплексное и не с плавающей точкой и даже не с фиксированной.

И не целое и вообще не число.

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

И как это может быть связано с тем, что указатель - это целое число?

Нет. Указатель – это не целое число. Для указателя не определены операции, которые определены для целых чисел, и наоборот.

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

p++ может выдать значение больше не на 1 совсем. Два указателя, целочисленные значения которых одинаковы, могут при сравнении выдать ложь. И так далее. Enjoy your C!

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

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

Реальность такова, что всё представляется нулями и единицами.

Теперь бегай с горелой жопой по всем топикам и пиши, что:

  1. Указатели это целое число
  2. Флоаты это целое число
  3. Картинки это целое число
  4. Текст это целое число
  5. Звук это целое число
anonymous
()
Ответ на: комментарий от anonymous

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

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

Для указателя не определены операции, которые определены для целых чисел, и наоборот.

Расскажи это процессору.

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

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

p++ может выдать значение больше не на 1 совсем.

И как это делает p не целым числом?

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

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

Enjoy your C!

Так я его и энджою даже очень.

Адреса у них не целые числа, ага. Клоуны, мля. Молятся на свои абстракции не имея ни малейшего понятия о том, как всё на самом деле работает.

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

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

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

https://wandbox.org/permlink/LSAK7dy3ZMNuWmxO

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

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

А я говорю, что могут. Вон даже анон выше ссылку дал с пруфом лол!

Адреса у них не целые числа, ага. Клоуны, мля.

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

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

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

да вообще-то может, но это нужно просто «железо» не на тех принципах что в ходу сейчас.

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

А после шланга пишет true.

А с какими параметрами? Потому что у меня false везде. И на том сцайте тоже false на последнем шланге.

К слову, ubsan из шланга тут даже не выстреливает :D

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

Потому что у меня false везде. И на том сцайте тоже false на последнем шланге.

Речь вроде шла про результат сравнения при одинаковом «численном значении», если вывод printf можно считать им. А в шланге численное разное.

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

Да, тоже заметил уже. Теперь шланг true показывает.

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

Если не знаешь как всё устроено - не лезь.

#include <stdio.h>
int  y = 2, x = 1;
int main()
{
  int *p;
  p = &x - 1;
  printf("&x=%p  &y=%p  p=%p\n",(void*)&x, (void*)&y, (void*)p); 
  _Bool b1 = (p==&y);   
  printf("(p==&y) = %s\n", b1?"true":"false");
  return 0;
}


gcc -O0 -o prog prog.c


$ ./prog
&x=0x404034  &y=0x404030  p=0x404030
(p==&y) = true
Stanson ★★★★★
()
Ответ на: комментарий от Stanson

Если не знаешь как всё устроено - не лезь.

К счастью, я знаю.

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

Если не знаешь как всё устроено - не лезь.

gcc -O0

Ты все свои программы собираешь с O0? Тогда понятно почему ты такой злой на жирные программы, и у тебя всё всегда тормозит :)

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