LINUX.ORG.RU

defer в C быть!

 ,


0

9

Привет, ЛОР!

Как я писал три года назад, в стандарт языка Си было предложено добавить выражение defer, выполняющее функцию или блок кода по выходу из области видимости, где оно было объявлено.

На днях данное предложение получило официальный статус и, скорее всего, defer появится в будущем стандарте C2y.

При этом, defer почти наверняка не будет добавлен в C++, так как его использование будет конфликтовать с другими частями этого языка.

Ссылка на пост в блоге автора: https://thephd.dev/c2y-the-defer-technical-specification-its-time-go-go-go

Спецификация: https://thephd.dev/_vendor/future_cxx/technical%20specification/C%20-%20defer/C%20-%20defer%20Technical%20Specification.pdf

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

Советую познакомиться с архитектурой проекта harbour.
Это core десятилетями отлаживалось и это действительно код профессионала хорошо знающего Си.

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

Собственно я об этом и написал, что требуется разный код. Пусть он даже физически в одном исходнике, с помощью #if, но сам код - разный. Вот, смотри по твоей же ссылке. https://github.com/harbour/core/blob/master/src/common/hbarch.c#L72

Программа просто обрастает множеством #if defined(...). Но это просто ужас сопровождать такой код, поэтому, стараюсь избегать этого, везде где только можно.

На мой взгляд, более переносимый код между процессорами получается, если использовать точные типы, которые есть в GNU GCC, например, int32_t и им подобные.

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

Проект harbour лет весь назад перевёл на C++ и сделал dll из которой можно дёргать API проекта.

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

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

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

Всё просто!

Вместо int используете INT, …

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

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

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

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

Некоторые аппаратные архитектуры не поддерживают long long … А тот код на который вы ссылаетесь, обеспечивает кроссплатформенную поддержку типа long long.

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

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

Так с любым кодом.

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

На мой взгляд, более переносимый код между процессорами получается, если использовать точные типы, которые есть в GNU GCC, например, int32_t и им подобные.

Они в стандарте, начиная с C99.

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

Может все-таки не аппаратные архитектуры, а компиляторы для этих архитектур?

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

И очень хорошо, если бы это встроено в компилятор, а не в библиотеку.

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

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

А вот не спешите судить о том в чём ещё не разобрались.

Сделал форк SDL, перевёл его на C++, убрал из проекта штук пятьдесят макросов, … Так вот все типы данных в проекте перевёл к исароьльзованию хедера из проекта harbour. Всё прекрасно работает!

Зря вы поспешные выводы делаете, да и много напраслины возводите неразобравшись.

Кстати разрабочик уже лет пять core не разрабатывает, так как сообщество ни разу ему ни в чём не помогло.

Это его слова, а не мои. Мне его искренне жаль.

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

Я же вам ответил, что никаких претензий к проекту я не выдвигал и не имел. Зачем вы на меня наезжаете понапрасну?

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

Это никак не противоречит примененному мегахэдеру в указанном вами проекту и ни как не уменьшает достоинств проекта.

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

Ваши слова - "Делать все проекты так, как этот, с мегахидером, увы, я не соглашусь. "?

Кстати все профессионально сделанные проекты на Си просто обязаны иметь такого рода хедер.

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

Дело вовсе не моём или вашем мнении, а в том как профессионально писать код на Си. Об этом речь. Так что не обижайтесь понапрасну.

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

В треде много утвержений о том что Си хорош и совсем мало советов как на нём писать хороший код.
Поэтому немножко поучаствовал в треде, но о многом ещё не сказал.

Те кто критикуют Си првы лишь в том, что чтобы писать хороший код на Си одних манулов по синтаксиcу недостаточно.

Однозначно!

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

Ребята, что вы на шаманы напали?

Он за какой интернационал второй или третий?

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

«тогда» случилось ещё смешнее

конвергенция модели вычисления С-машины (некая редукция перечения pdp-кокойто ) и (микро)процей-куркуляторов-переростков

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

как раз в этом смысле golang это больший си чем си теперь

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

Много раз говорил и ныне скажу.

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

Грамматики все аораждаю лавину, как маленький камешек, катящийся с горы.

Не тратье время попусту.

Грамматика дожна быть не сложнее словарного запаса Эдлочки.

Шалите парниши!

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

Куплю новую клавиатуру. На нынешней многие буквы проглатываются и текст неряшлив.

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

в этом смысле golang это больший си чем си

кому и кобыла невеста (с)

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

Грамматика дожна быть не сложнее словарного запаса Эдлочки.

Простота, чистота, правота — наилучшая красота (с)

походу я уже стал цитатами и пословицами разговаривать

надо еще научиться назидательно воздевать палец и можно идти в аксакалы

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

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

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

Нет нельзя ), УБ - это высокоуровневая фича, как и сам язык Си, и не зависит от реализуемости в железе

просто кастом снимаешь конст и тестируешь как работает аппаратная защита.

const char* ls = "dasdasd";

int main() {
    *(char*) ls = 0;
}
alysnix ★★★
()
Ответ на: комментарий от anonymous

весьма красива.

на красоте то мы все и попадаемся

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

Тема весьма интересна. Обсудить бы её в отельном треде …

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

Хомский(нонешней? не преждний(каждые 10 лет после линьки совсем иной)

объясняет весь естественный язык через всего 2 правила - типо такое эволюционно возможно а не всякие выверты с контекстными грамматиками как вершиной иерахии грамматик 50ых Хомского

[1]https://ru.wikipedia.org/wiki/Минималистская_программа

не спутывать с Колмогора длиной

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

в общем случае, если нет аппаратной защиты, а структурные константы лежат в писабельной области памяти(а не в rom), можно и на си их попортить. и на с++

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

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

В программировании всегда нужно стараться выбрать приемлемый инструмент для «забивания» проектов.

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

Любой, любой процессор исполняет код из одного, единого адресного пространства.

Нет. ARM умеют выполнять код прямо с флешки, например.

Сейчас нет процессоров с несколькими разными адресными пространствами.

Есть, в различных видах. Начиная от примера с флешками выше и заканчивая NUMA.

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

Т.н. «близость» к процессору тут не причём. Это вопрос наличия рантайма и его портируемости. Rust и многие другие языки обладают тем же свойством.

А, например, C# без динамической памяти попросту невозможен.

Для C# были рантаймы, работающие поверх голого железа. Это не то чтобы большая сложность.

Только не надо вдаваться в крайности и всё пытаться делать только на Си или только на C#. Каждый язык удобен для своей задачи.

Очень общее утверждение, лишённое смысла.

Т.е. я тоже против всяких defer языке.

Всем насрать на то, против ли ты. В Си уже есть defer в виде компиляторных расширений: в GCC/Clang это __attribute__((cleanup)), и код с ними УЖЕ в твоей системе. В заглавном посте я написал про добавление уже существующего функционала в стандарт языка.

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

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

что значит «может»? я снимаю const кастом, вполне легальным для си и пишу куда хочу.

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

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

Это ничем не отличается от

char* ls = "dasdasd";

int main() {
    *ls = 0;
}

Здесь UB из-за записи в строковый литерал "dasdasd".

PS. Единица трансляции без #include (какого либо [вложенного]) стандартного хидера тоже UB.

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

вы как бы намекаете, что такой файл не соберется и не запустится?

PS. Единица трансляции без #include (какого либо [вложенного]) стандартного хидера тоже UB.

чем провинился main просто возвращающий код? Опять же непонятно, что такое «стандартный хидер». Хидер это просто декларации, которые в виде текста вставляются в данный файл.

Некие левые «стандартные» декларации, вовсе не используемые в данном TU, снимут UB? Боже в каком мире мы живем. Короче, вы что-то путаете.

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

вы как бы намекаете, что такой файл не соберется и не запустится?

Я намекаю то, что написал. В Си const практически имеет только декоративный смысл, который модно снять или установить, как захочется.

Неопределенное поведение - из-за записи в строковый литерал.

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

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

Фу на тебя, я уж засомневался, думал в сишке константы тоже сломаны, проверил: https://godbolt.org/z/38E6rfTE9 - таки уб, в кланге уже с O0 а в gcc c O1 у тебя будет: «ААА!! компилятор сломали! в комитеты прорвались жаборасты!! НИАСИЛИЛИ!!» и т.д.

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

что значит «может»? я снимаю const кастом, вполне легальным для си и пишу куда хочу.

Нет, не легальным.

An attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type (6.7.3)

Страница 508 из вот этой pdf. Про то, что творит компилятор, тебе @zurg уже написал. Сишные треды с твоим участием были бы куда интереснее, если ты хотя бы немного знал Си. Но ты его нихрена не знаешь.

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

С пониманием чего, неопределенного поведения?

Строковый литерал может быть захордкожен в код (секцию кода), или какую-нибудь другую секцию только для чтения. Как эти секции слинкуются в бинарь, как этот бинарь с секциями загрузиться в память, это не определено. Не известно какая защита сработает или не сработает в виду отсутствия, например, попытка установить флаг WR(запись) для страницы кода, куда захордкожен строковый литерал, или попытка выполнить код из страницы с WR, или запись в RO и тд и тп. Зависит от линкера (binutils и тп.), загрузчика (ld.so и тп, ядро) и тд.

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

Пример не эквивалентный (хотя смысл одинаковый).

У него объявляется обычный указатель, а не константа (константная переменная).

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

У тебя пример левый, не про то.

Я показывал, как попытаться записать в область строковых констант, нечто, и что компилятор меня не остановит.

Там в рантайме будет сегфолт, если защита памяти.

А если на какой нить железке защиты не будет(а защита вовсе не обязательно есть в железе, и вовсе не обязательно задействована, даже если есть) - то память будет расписана.

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

Тогда ругаться надо, а не тихо удалять этот код.

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

вот так попробуй, мне лениво.

короче - задача неземетно для текущего TU снять каст с указателя.

делаешь внешнюю функцию cast, в которой снимаешь с указателя const. она в другом файле, и обьявляешь ее тут чeрез extern, или инклудишь заголовок.

при компиляции мейна канпилятор не понимает, что в той функции делают каст, и тупо должен вписать по адресу твоего була true.

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

void ft(){puts("true");}
void ff(){puts("false");};

///это внешняя функция долна быть
bool* do_cast(const bool* fp) {
    return (bool*) fp;
}

void tst(){
   const bool fl = false;

    //*((bool*)&fl) = true;
    * do_cast(&fl) = true;
    
    if( fl) {
        ft();
    }else{
        ff();
    }
}

int main(){
    tst();
}
alysnix ★★★
()
Ответ на: комментарий от hateyoufeel

в Си не могут добавить вывод типов.

Да вообще-то есть зачатки. __auto_type или можно по старинке через typeof()

Проблема не с назначением типа i. Проблема в том, что если оно будет не int, то компилятор может завалить тебя теми же самыми варнингами но уже про десятки переменных, которые традиционно int и которые должны взаимодействовать с i который уже не int из-за auto i; или, например, typeof(size) i;

Это вторая причина не любить сишечку: очень уж убогонький говноязычок.

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

Убогонький говноязычок это какой-нибудь раст. Причём совсем не по техническим причинам.

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

«эта хрень» проистекает из представления signed и unsigned типов в памяти машины

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

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

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

Да нет, тут как раз не дебилу, варнинг полностью по делу.

Он будет по делу только и исключителько в том случае, если size реально может оказаться больше MAX_INT. Вот только тогда и нужно выводить варнинг. А если все возможные значения size в компилируемых сырцах получаются исключительно из strlen() от строковых констант из нескольких букв или размеров локальных буферов по 16-64 байта, то компилятор должен молчать в тряпочку даже если i это char.

Ну вот, нуб поленился исправить сотни некорректных типов

А это не его типы. Это типы которые возвращают или с которыми работают библиотечные функции. И типы абсолютно корректные.

Обычно ничего такого нет,

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

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

Да вообще-то есть зачатки.__auto_typeили можно по старинке черезtypeof()

Это не часть стандарта была. Теперь есть.

Проблема в том, что если оно будет не int, то компилятор может завалить тебя теми же самыми варнингами но уже про десятки переменных, которые традиционно int и которые должны взаимодействовать с i который уже не int из-за auto i; или, например, typeof(size) i;

Ну так может надо использовать один и тот же тип и аккуратно кастовать всё? Да нет, бред какой-то.

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

Ты про JavaScript сейчас? Потому что JavaScript по количеству строк оставляет сишку позади. Да и Java тоже. Что не мешает им быть абсолютно ублюдочными языками, хоть и по другим причинам.

hateyoufeel ★★★★★
() автор топика
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)