LINUX.ORG.RU

Проект на чистом Си

 , , ,


7

13

Камрады, всем доборый день!

Решил тряхнуть стариной, написать кое-что полезное для себя и таких же упоротых личностей. Заодно вспомнить Си (который без «крестов»). Естественно, хочется сделать «красиво, модно, молодёжно» и удобно. Вопрос - как проекты на Си принято начинать в 2024? Ну там пакетные менеджеры (а они вообще есть?), линтеры и прочее счастье. Какой стандарт сейчас считается «правильным» для использования и какую литературку/доку по нему почитать? Буду благодарен, если покидаетесь статьями или книгами.

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

В linux syscall api.
Но конечно же писать без libc решение весьма не универсальное.
Уже были попытка создания универсальных libc чтобы отвязать софт от системной libc (nacl, cosmopolitan libc), но, похоже, все они заброшены.
Единственный проект, который справляется с этим и до сих пор актуален - wine, а portable executable - чуть ли не единственный дейатвительно портативный формат исполняемого файла

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

сам я не осилил С++. Слишком умно для меня.

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

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

Пишут на нём только остановившиеся в развитии деды

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

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

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

Например при написании под микроконтроллеры с малым количеством ОЗУ такой подход вполне имеет смысл.

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

А meson или cmake даже для hello world из одного файла строго обязательны.

Почему-то в микроконтроллерных исходниках (под AVR в частности) я использования cmake не вижу. Хотя так как раз файлов обычно немного. Хотя мейкфайлы там довольно солидные (даже если не смотреть на запуск софта программатора из них - всё равно обычно его запускаю отдельно. Я бы показал свой из недавнего проекта но там аж восемь килобайтов - на форум столько неприлично будет вставлять,да и всё форматирование поедет.

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

Хороший набор из строгих -Werror к компилятору

А бывает такой набор чтобы GCC предупредило что в этом коде не только разные типы складываются,так еще и результат молча обрезается при присваивании? Ни -Wall ни -pedantic не помогают.

typedef int sometype ;

int main()
{
    int i;
    sometype j;
    long int k;

    i=0xFFFFFFFE;
    j=10;

    k=i+j;
}

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

Потому что эмбедщики лютые быдлокодеры.

Отчасти соглашусь. Но есть и те кто старается писать аккуратно. Вот например такой мэйкфайл имеет смысл пытаться на cmake переделать? https://dropmefiles.com/Mvgdl Там используется способность gcc генерировать файлы с зависимостями и это очень полезно.

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

Я не знаю, я просто во всех мелких тулзах вижу месон и он работает идеально. Флаги, зависимости, pkgconfig, кросс-цомпилирование. Накидал конфиг в двадцать строк и у тебя все хорошо.

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

Быстрый

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

понятный синтаксис конфигов

А можно было уже имеющийся ЯП взять, а не выдумывать синтаксис конфигов, у вас и так питухон

4 питоновских модуля

то есть одного питухона им мало было?
Так же там в зависимостях ninja, хотя это не такая уж и проблема.
В итоге, чтобы mesa под систему 14 года в 18 году собрать (по сути актуальная LTS на тот момент), мне приходилось собирать питон, кучу модулей, а потом ещё править ninja файл, потому что ninja из системы его не понимал...

Где недостатки?

Те же проблемы что и с автотулзами. Постоянно такое происходит, что меняю конфигурацию, делаю reconfigure, а он не пересобирает часть файлов с новыми опциями, или опции не применяет. А иногда несколько обратная проблема - малейшее изменение в флагах линковки тригеррит пересборку ВСЕГО.
Вроде как системы сборки существуют, чтобы этого избежать. Это было извечной болячкой автотулза, делающего его совершенно бесполезным, но и это в meson взяли
Или ещё пример - в ninja-файле записался запуск переконфигурации самим meson'ом при каких-то условиях. Казалосб бы, зачем вообще генерить ninja-файл если он всё ещё зависит от meson, но опустим это. Запущенный meson уже запускается с другими енвами и выставленные енвы для конфигурации отваливаются. В итоге пакет незаметно при запуске ninja переконфигурируется С ДРУГИМИ ПАРАМЕТРАМИ
Я не отрицаю, что преимущества перед автотулзами у meson в каких-то аспектах могут быть, но глобально он не чем не лучше
Даже у cmake дела обстоят куда лучше со всем вышеперечисленным. Да, там тоже проблемы с синтаксисом, там тоже ад зависимостей и версий, но cmake даже бутстраппер держит в репе, который позволяет собрать его с нуля, когда нет никакой версии cmake в системе и не искать где, какие и куда нужно питоны ставить.
Так же есть waf, который зависит от питона без сторонних модулей, он просто будет работать если в системе есть хоть какой-то питухон, а если нет - можно притащить любой питон и не придётся настраивать всякие окружения. чтобы доставить туда дополнительные модули. И waf не нужен какой-нибудь make или ninja, он запускает процессы сам, а пересборку контроллирует по контрольным суммам, а не по времени, а конфиг - обычный питоновский модуль, дополненный апишками.
Наверно ещё есть хорошие системы сборки. Но meson уж точно не среди них

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

Конфигурация всё равно долгая. да, совсем банальные проверки убрали, но всё равно проверяет всё последовательно

Да в смысле:

meson setup build  0.71s user 0.39s system 123% cpu 0.891 total                                                                                                 

А можно было уже имеющийся ЯП взять, а не выдумывать синтаксис конфигов, у вас и так питухон

DSL это удобно. Я не хочу программировать на языке для сборки :D

В итоге, чтобы mesa под систему 14 года в 18 году собрать (по сути актуальная LTS на тот момент), мне приходилось собирать питон, кучу модулей, а потом ещё править ninja файл, потому что ninja из системы его не понимал…

это что за система где нет python 3.4?

А иногда несколько обратная проблема - малейшее изменение в флагах линковки тригеррит пересборку ВСЕГО.

Это кажется не так проблема, ей богу.

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

ТС с Тюмени (по профилю). Вспоминая историю DDB, думаю, что тема не взлетит, можно и не начинать.

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

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

это что за система где нет python 3.4?
14.04 comes with Python 3.4

видимо, на практике 3.4 ему не хватает. Так то 3.4 это действительно вполне адекватое требование. Возможно этого не хватало какмоу-то требуемому модулю, но факт остаётся фактом - для mesa приходилось собирать кучу всего, а синтаксис ninja не такой уж и стабильный. Да, я понимаю, что говорить про 14.04 в 2024 году через почти 10 лет с релиза глупо, но это лишь говорит о факте - бутстрапить систему сборки с нуля если зависимостей нет в системе сильно сложнее чем в случае autotools, cmake и waf

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

meson setup build 0.71s user 0.39s system 123% cpu 0.891 total

таки сделали параллельную конфигурацию? ну ладно, ещё одним плюсом больше

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

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

Это кажется не так проблема, ей богу.

Собирал проект 3 часа, он не сликовался из-за забытого разрабами -lrt (спасибо glibc, что перелопатили библиотеки)
Так давай же соберём его ЗАНОВО!!!

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

Так а никто не осилил: это как сосчитать сколько капель в море

Гы, оказывается, призказка-то работает – что программисты делятся на 2 категории: те, кто освоил C++, когда он ещё был простой, и те, кто его никогда не освоит.

На cppcon когда-то вещала какая-то весьма известная и авторитетная в тех кругах тётка-препод, которая толкала идею, что начинающим не надо давать адресную арифметику и прочую дичь, а ТОЛЬКО высокоуровневый «прикладной» C++: например, строка – это std::string и баста; конкатенация строк - это s1 + s2 и ничто другое.

Голый сь, включая 0-terminated строки, разумеется будет вылезать постоянно – при системных вызовах, хз как она эту проблему решает.

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

Голый сь, включая 0-terminated строки, разумеется будет вылезать постоянно – при системных вызовах, хз как она эту проблему решает.

На самом деле, про него не нужно знать вообще. В Rust есть CString, в который ты конвертируешь и не больше не страдаешь.

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

начинающим не надо давать адресную арифметику и прочую дичь

С другой стороны, если человек приходит из сей, то для него дичью будет как раз вся эта из себя объектность. Тут могу только присоединиться к каменту @untitl3d: переименовываешь исходник .c в .cpp и продолжаешь писать на голом си. Компилятор будет более свирепым, чем с .c: например, касты из void* в Type* надо будет делать явными – а больше поначалу вроде ничего особенного. А потом потихоньку можно начинать какие-нибудь плюсявые штучки заюзывать, всё равно какие. Рано или поздно наберётся критическая масса, и появится понимание, где что можно заюзать и куда дальше смотреть.

Помню, свой первый класс под названием List (хотя это был эквивалент vector<int>) я пытался скомпилировать 2 или 3 дня. :)

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

если человек приходит из сей

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

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

Помню, свой первый класс под названием List (хотя это был эквивалент vector) я пытался скомпилировать 2 или 3 дня. :)

Да в сях всё так. Вот, вроде, ничего не делаю, пишу или в начало выделенного куска памяти, или в конец. Если в начало - DOS крашится, после окончания работы программы. Если в конец - нет. Чёрт его знает, что ему не так.

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

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

Нет дженериков, нет банальной хеш-таблицы, каждый второй проект пердолит свои строки. Отличный язык!

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

Нет дженериков, нет банальной хеш-таблицы, каждый второй проект пердолит свои строки. Отличный язык!

тем и отличный, что простой и нет в нем всякого мусора, вшитого насмерть

alysnix ★★★
()

как проекты на Си принято начинать в 2024

С оглядкой на 16битные системы и Big-Endian, а по сему строго сидеть на ANSI C. В CI/CD необходимо иметь два pipeline: первый для сборки через компилятор от Turbo C 1.0 и тестированием в MS-DOS 5.0 (за одно проверишь соблюдение стандарта языка + нестандартная система базовых типов), второй --- для эмуляции чего-нибудь на PowerPC для проверки работы с памятью на нестандартной архитектуре (например, через QEMU можно запустить Debian 8 для PPC с Big-Endian, но будь готов к нереально медленной работе). Дополнительно рекомендуются pipeline для тестирования густо смазанных санитайзерами сборок, а также для суточного fuzzing тестирования.

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

тем и отличный, что простой и нет в нем всякого мусора, вшитого насмерть

Так он очень сложный из-за этого. Тебе постоянно приходится сражаться с комитетом, с компиляторами, с небом и аллахом. Есть хочется простоты – есть zig.

cumvillain
()

Естественно, хочется сделать «красиво, модно, молодёжно» и удобно.

Так не получится.
При разработке нет необходимости «косички заплетать».

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

overflow и conversion.

О! спасибо, -Wconversion помогло - появилось предупреждение о возможном переполнении. Я-то думал что сочетание -Wall и -pedantic включает все возможные предупреждения. Теперь стало интересно, какие еще оно НЕ включает?

Возможно в clang-tidy есть.

В дебиане есть пакет «clang-13». Надо будет пощупать хотябы на десктопе. Плохо только то,что под микроконтроллеры обычно есть только gcc.

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

Даже -Wall -Wextra -Wpedantic не включает вообще всё. Читай документацию на GCC, посмотри какие полезны и включай их вручную, постепенно исправляя класс потенциальных ошибок. По крайней мере это работает лучше, чем включение -Wextra -Wpedantic которые как по мне только вредят флудом, который никто не читает.

В Clang есть -Weverything, который как раз включает всё, но он ещё хуже. Опять же из-за флуда.

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

В итоге, чтобы mesa под систему 14 года в 18 году собрать (по сути >актуальная LTS на тот момент), мне приходилось собирать питон, кучу >модулей, а потом ещё править ninja файл, потому что ninja из системы его >не понимал…

И это - совершенно обычное явление в линуксе к сожалению. У меня вообще ощущение такое,что несовместимости в базовые системные вещи вносятся специально и целенаправленно с какими-то корыстными целями. Очень уж это частое явление чтобы списать на случайность/невнимательность/еще что-то непроизвольное.

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

Так старые файлы удалять надо перед запуском reconfigure.

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

В 2024 не принято начинать проекты на си.

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

Я бы например писал для микроконтроллеров на ADA,но пока что у gnat с поддержкой МК весьма не очень. Есть проект avr-ada,но сильно недоделаный и к практическому применению малопригодный. Я таки пытался.

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

std::string и баста; конкатенация строк - это s1 + s2 и ничто другое.

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

Голый сь, включая 0-terminated строки, разумеется будет вылезать постоянно > при системных вызовах, хз как она эту проблему решает.

Напишет поверх системных вызовов библиотеку,которая и будет ей строки конвертировать. Вон, в ADA есть несколько разных вариантов реализации строк,и системным вызовам это никак не мешает. Я кстати четверть века назад написал для Ады (Meridian ADA for DOS) реализацию 0-terminated строк, и их можно было складывать s1+s2 за счет переопределения операции «плюс». Оно работало и я этим пользовался.

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

С другой стороны, если человек приходит из сей, то для него дичью будет >как раз вся эта из себя объектность.

Не смешиваем в одну кучу объектный подход к написанию программы и синтаксис С++. Дичью будет именно синтаксис. А так-то писать в объектном стиле можно и на обычном Си. Как пример - библиотека текстового пользовательского интерфейса CScape ((c) 1989, Oakland Group, Inc). В 90х я много с ней работал. В том числе сделал bindings для использования с Meridian ADA compiler for DOS.

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

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

Полностью согласен! Единственная проблема в том,что если программа становится большой то фактически вручную следить за распределением памяти (контроля-то никакого нет) - становится утомительно. Поэтому-то в больших проектах регулярно и вылезают то выходы за границу массива,то use after free.

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

У меня вообще ощущение такое,что несовместимости в базовые системные вещи вносятся специально и целенаправленно с какими-то корыстными целями.

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

mittorn ★★★★★
()