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

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

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

hateyoufeel ★★★★★
() автор топика

Почти как Perl, только без автоматического управления памятью.

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

По твоей логике указатель и указатель на массив — это разные типы.

Так и есть. Указатели на разные типы – это тоже разные типы.

Ты упорот?

Да. Я стандарт языка прочитал.

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

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

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

Где я торможу-то?

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

Так и есть

Чем отличается указатель на «переменную» и указатель «на функцию» во всех популярных процессорах? Ничем. Это просто число, обозначающее ячейку в виртуальной памяти. В первом случае откуда нужно взять n байт, во втором, куда нужно передать управление. Это архитектура фон Неймана, иди мат. часть учи, лалка.

Я стандарт языка прочитал

Молодец. А теперь забудь это говно.

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

Эта «пурга» нужна для того чтобы Си был переносимым системным языком.
И никакой это не высокоуровневый ассемблер.

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

По IP Шома может только свой анус забанить. Сменить IP в интернетах сейчас проще чем презерватив поменять между подходами.

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

Чем отличается указатель на «переменную» и указатель «на функцию» во всех популярных процессорах? Ничем. Это просто число, обозначающее ячейку в виртуальной памяти. В первом случае откуда нужно взять n байт, во втором, куда нужно передать управление. Это архитектура фон Неймана, иди мат. часть учи, лалка.

Ты ещё скажи, что твой процессор является фон Неймановским в присутствии W^X (оно же NX). У тебя даже кэши в процессоре отдельные для инструкций и для данных. Пластмассовый ми^W^WГарвардская архитектура победила. Страдай теперь.

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

Молодец. А теперь забудь это говно.

Прости, но согласно этому говну (я, кстати, абсолютно согласен, что стандарт C – ад и холокост) пишут компиляторы. Игнорировать его – себе же хуже.

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

Где я торможу-то?

Компилятор считает, что они никогда не равны, потому что ни одно из условий не удовлетворяется. И заменяет проверку на константный false.

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

В набат сразу. Авторам. (Авторам чего, уточнить в процессе, вдруг не тем)

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

Придётся завести себе VPN в Брно на том же провайдере, на котором Шома сидит, чтобы Шома и его забанил.

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

Не, это я догнал, я теперь про сам подход, описанный в стандарте.

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

Где я торможу-то?

Не нужно ничего усложнять, делай как можно проще и всё.

Я для себя решил просто не сравнивать указатели на разные объекты и всё.

А так там в twitter даже часть ответа выложили на этот баг репорт, который нашёл аноним :)

Just because two pointers print the same and have the same bit-pattern doesn't mean they need to compare equal
fsb4000 ★★★★★
()
Ответ на: комментарий от Oberstserj

Ну вообще, адрес Шомы где-то кем-то сливался, и у нас была мысль нанять нескольких страшных жирных трансвеститов, которые бы парадировали в бикини по его улице и скандировали лозунги «ШОМУ ВОН ИЗ МОДЕРАТОРОВ!» и «ШВИМ!!» с чудовищным чешским акцентом.

Но мы с парнями в итоге решили, что пока что это перебор.

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

А так там в twitter даже часть ответа выложили на этот баг репорт, который нашёл аноним :)

Just because two pointers print the same and have the same bit-pattern doesn't mean they need to compare equal

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

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

В штанах у тебя ЛОЛ.

В модели исполнения C заложена, например, плоская модель памяти. При этом, модель памяти современных процессоров примерно настолько же плоская, как сиськи бывалой порнозвезды после третьей имплантации силикона в них. Кэши, NUMA и прочие ништяки типа RDMA всё портят.

Современные процессоры и ОС довольно паршиво пытаются эмулировать абстрактную машину C, которая в свою очередь смоделирована на основе PDP-11. Но современные процессоры являются чем угодно, но не потомками PDP-11 и имеют совершенно иную архитектуру. Отсюда получаются всякие Meltdown и Spectre, среди прочего говнеца.

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

В модели исполнения C заложена, например, плоская модель памяти

Шо?!

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

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

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

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

Кэши, NUMA и прочие ништяки типа RDMA всё портят.

Мляя... Это все под капотом у процессора. Для программ этого всего говна не существует(кроме ОС). Рыночек прешал и ВЛИВ закопали. Но вот недавно все пососали бибку из-за этих микроархитектурных костылей, но позно пить боржоми.

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

Но мы с парнями в итоге решили, что пока что это перебор.

Какая непростительная ошибка

Oberstserj ★★
()

RAII. всё необходимое есть там.

мне фанатики экзотических языков типа раста и го напоминают свидомых. один в один:

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

вот-с, придумали вместо правильного RAII например на базе std::unique_ptr употреблять местечковое defer. которое хз вообще как реализовывать. что кстати говорит и о качестве «проектирования» этих самых растов и го, вся идея состоит лишь в том, чтоб изголяться «абы не как у С++».

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

Мляя… Это все под капотом у процессора. Для программ этого всего говна не существует(кроме ОС).

Член твой под капотом у процессора. Эффекты от кэшей весьма и весьма очевидны при выполнении пользовательских программ, и часто код можно ускорить, если знать об этом. Посмотри исходники игровых движков. Там это весьма обильно используется. А истории про локи и сброс кэшей и вызванные этим баги – это вообще огонь.

Ну или вот тебе офигенная история про баг в Mono: https://www.mono-project.com/news/2016/09/12/arm64-icache/

Никаких ОС, всё исключительно в юзерспейсе. И тем не менее!

Для работы с NUMA вообще отдельная библиотека есть, и иногда ей приходится пользоваться, когда пишешь серверный софт на C.

Рыночек прешал и ВЛИВ закопали.

VLIW – это про выполнение программ, а не про память. То, что Out of Order Execution зарулил, это безусловно факт, но здесь это не причём.

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

Это совершенно плохая аналогия.

И, если что, современный веб это наследник именно IE стандарта, а не стандарта от бюрократов, занимавшихся только производством спецификаций. Поползновения бюрократов по придумыванию своего направления развития html закапывались как минимум два раза - один во времена html3-html3.2, второй с xhtml.

firkax ★★★★★
()
Ответ на: комментарий от thesis
int a = 228, b = 228;

int main()
{
  int *p = &b - 1;
  return 0;
}

gcc -S -masm=intel main2.c -m32 -O0

        .file   "main2.c"
        .intel_syntax noprefix
        .text
        .globl  a
        .data
        .align 4
        .type   a, @object
        .size   a, 4
a:
        .long   228
        .globl  b
        .align 4
        .type   b, @object
        .size   b, 4
b:
        .long   228
        .text
        .globl  main
        .type   main, @function
main:
....

gcc -S -masm=intel main2.c -m32 -O2

	.file	"main2.c"
	.intel_syntax noprefix
	.text
	.section	.text.startup,"ax",@progbits
	.p2align 4
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	xor	eax, eax
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.globl	b
	.data
	.align 4
	.type	b, @object
	.size	b, 4
b:
	.long	228
	.globl	a
	.align 4
	.type	a, @object
	.size	a, 4
a:
	.long	228
	.ident	"GCC: (GNU) 11.1.0"
	.section	.note.GNU-stack,"",@progbits
BceM_IIpuBeT ★★☆☆☆
()
Ответ на: комментарий от hateyoufeel

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

Будет багом ОС, в которой это допустили. Допустив несовместимые версии компилятора и libc вместе.

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

Эта «пурга» нужна для того чтобы Си был переносимым системным языком. И никакой это не высокоуровневый ассемблер.

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

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

abcq ★★
()

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

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

@ox55ff

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

Ясно, спасибо. И что ж дурного в этой практике? По крайней мере это все осуществляется по воле программиста, а не как-то само непонятно как фоном работает

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

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

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

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

Для этого есть memset_s, которая более-менее стандартная (ISO/IEC 9899:2011 (“ISO C11”) K.3.7.4.1).

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

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

–не-выкидывать-мемсет-при-оптимизации – может вызывать трабылы?

А вообще, складно говоришь – я внял

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

–не-выкидывать-мемсет-при-оптимизации – может вызывать трабылы?

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

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

Это explicit_bzero теперь стандартный (раньше был только в продвинутых BSD, теперь и до линуксового glibc дошёл). А memset_s - только на бесполезных бумажках.

#include <string.h>
#include <strings.h>

int main(int argc, char * * argv) {
  explicit_bzero(argv, 1);
  memset_s(argv, 0, 1);
  return 0;
}
$ gcc x.c
x.c: In function ‘main’:
x.c:6:3: warning: implicit declaration of function ‘memset_s’; did you mean ‘memset’? [-Wimplicit-function-declaration]
    6 |   memset_s(argv, 0, 1);
      |   ^~~~~~~~
      |   memset
/usr/bin/ld: /tmp/cczX69e1.o: в функции «main»:
x.c:(.text+0x3b): неопределённая ссылка на «memset_s»
collect2: error: ld returned 1 exit status

Говорю ж, стандарт это gcc а не графомания от всяческих комитетов.

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

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

Не позорься. defer придумали давным давно, когда ни Go, ни Rust не было в проекте. Реализуется defer элементарно, и давно используется. Пропозал добавляет гибкости и закрепляет существующую практику в стандарте.

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

Говорю ж, стандарт это gcc а не графомания от всяческих комитетов.

Какое отношение имеет компилятор к наличию реализации какой-либо функции в стандартной (или не очень) библиотеке?

Для memset_s() в glibc нужно:

#define __STDC_WANT_LIB_EXT1__ 1

В FreeBSD и illumos доступны и без дефайна (но правильней с ним).

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

Функция explicit_bzero(), на которую так все молятся, на самом деле точно так же может перестать работать в каком-нибудь новом компиляторе.

Не может, это будет нарушать правила языка.

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

Ага. Потому что наверняка есть куча кода, которая работает потому что memset() выкидывается.

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

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

Какое отношение имеет компилятор к наличию реализации какой-либо функции в стандартной (или не очень) библиотеке?

Да, ты прав, я ж сам про это писал выше. Следует переформулировать как-то.

Для memset_s() в glibc нужно:

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

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

Не существует необходимости делать _explicit вариант для каждой функции.

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

Как это связано с обсуждением сравнения указателей, которые, будучи побитово равны, не считаются одинаковыми?

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

Это детали реализации explicit_bzero, тушка которой может быть в другой библиотеке или вообще хз где. Если ты вызываешь explicit_bzero и передаёшь туда переменную, не объявленную как volatile, то где здесь нарушение правил? Я не вижу, честно говоря. Особенно при раздельной компиляции.

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

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