Перейти к содержанию
    

как писать на С в 2016 году

Изучая исходники с github, заметил, что в качестве основного рабочего объекта определяется одна глобальная структура, содержащая все переменные и указатели на функции. Далее в main создается эта структура и все манипуляции производятся с ней.

Кажется это немного не то о чем вы написали...Либо ваше описание немного не точное и сразу представляется что-то другое.

А по ссылке представлен классический пример того, как на Си реализуется объект и его методы. При этом программист передает методам ссылку на объект в явном виде.

В С++ это быо бы класс и описанные вами данные были бы закрытыми членами класса, а приведенные функции - публичным интерфейсом класса. При этом за кулисами происходит то-же самое - компилятор генерирует кучу функций и неявно передает им указатель на структуру с данными (*this).

 

Так что этот подход вполне валиден и стар как мир.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кажется это немного не то о чем вы написали...Либо ваше описание немного не точное и сразу представляется что-то другое.

А по ссылке представлен классический пример того, как на Си реализуется объект и его методы. При этом программист передает методам ссылку на объект в явном виде.

В С++ это быо бы класс и описанные вами данные были бы закрытыми членами класса, а приведенные функции - публичным интерфейсом класса. При этом за кулисами происходит то-же самое - компилятор генерирует кучу функций и неявно передает им указатель на структуру с данными (*this).

 

Так что этот подход вполне валиден и стар как мир.

Вот это и имел в виду. А в чем разница? :rolleyes: Там надо пройтись по ссылкам, конкретно не выбирал, где описана сама структура.

http://libopencm3.github.io/docs/latest/us...rce.html#l00047

Может, и старо. Но я к этому подхожу лишь сейчас. Обусловлено сложностью проектов.

Си, вообще, старик, ничего нового ожидать не приходится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто по вашему описанию и у меня и у smalcom, как я понял, сразу возникло впечатление что описывается какой-то "говнокод-подход" по глобализации всех переменных программы )) Что является тем еще злом!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не знаю на счет веб дизайна и компьютерщиков, но помоему самые святые постулаты о том, как правильно писать на ембеддерном Си, пишет NASA в своих гайдлайнах и стандартах. Например http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf

http://homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf и аналогичные. И подходят они и к Си1980 и к Си2016.

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

Как по мне маст ноу каждого начинающего ембеддерного программиста.

К ним еще MISRA-C:2004 можно добавить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

С ПО нужно провести такую-же аналогию. MISRA надо там где надо )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

описывается какой-то "говнокод-подход" по глобализации всех переменных программы

да, также подумал.

 

имхо тема как раз про красивое и/или надёжное программописание. Т.е. не для мигалки. Потому что быдлокодить можно внезависимости от эпохи и языка. Если честно - я так и не понял чего хочет ТС, плюс немного тема привлекла софистов. MISRA - это плюс. Как я вижу процесс обучение - сначала учим правила, выводим закорючки, а когда всё это "отскакивает от зубов" - балуемся эрративом.

 

С ПО нужно провести такую-же аналогию. MISRA надо там где надо )

абсолютно в дырочку: одна из задач инженера - минимизировать расход ресурсов при выполнении той же задачи

 

:bb-offtopic:

будучи "малышом" я так свой первый втык получил: при ремонте на объекте запаниковал и заменил нерабочее реле новым... стоимостью 15 кредитов. Хотя рядом был радиобазар и можно было прикупить нужное за 1-2 кредита.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

libopencm3
Раз уж затронули эту либу...

Меня лично напрягает их подход:

для работы с периферией используется номер (например номер UART: void usart_set_baudrate (uint32_t usart, uint32_t baud)), а у меня все мои либы используют обычно указатель на хэндл того же UART.

Что, на мой взгляд гораздо прямее, т.к. не нужны никакие if-else по номеру, а сразу usart->sfr.BRR =XX.

Именно поэтому я до сих пор не использую libopencm3, хотя идея прекрасная и code-style правильный...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И подходят они и к Си1980 и к Си2016.

 

О тут бы не согласился.

Стиль языков это отражение свойств редакторов, библиотек и средств разработки этих языков.

Очевидно же что пишущий в Notepad (что в прошлом и было) будет пропагандировать совсем другой стиль чем пишущий в Visual Studio с установленным Visual Assist.

Совершенствуются средства разработки и соответственно меняется стиль. Причем в корне.

 

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

 

С другой стороны есть такие статические анализаторы как С-STAT у IAR. Крутейшая вещь. Никакой MISRA не надо.

Это тоже отправляет добрую часть старых рекомендаций в топку. С-STAT всё сам найдет и укажет что исправить.

 

Короче в 2016 будет продолжаться ослабление требований к стилям и усиливаться индивидуализация кодирования. То что некоторые называют "говнокодом". Хотя, надо бы банить за применение такого определения.

 

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То что некоторые называют "говнокодом". Хотя, надо бы банить за применение такого определения.
Т.е. книгу М.Фаулера Рефакторинг вы тоже не рекомендуете? А ведь там как раз вполне серьезно вводится понятне code smells и даже проводится аналогия с детскими пеленками кажется ))))

 

Нет уж. Говнокод это как раз таки абсолютно обоснованное понятие. И это не то-же самое, что разные стили оформления кода(на что будет влиять упомянутый Visual Studio с Visual Assist). В процессах построения ПО уже все хорошо изучено и изложено. Каталогизировано по степени запаха. И даже с примерами. Реально тот-же Фаулер прямо четко и конкретно указывает какие признаки обладают дурными запахами и что можно сделать и почему это нужно сделать(примеры из разных жизненных ситуаций почему проект потом в это упирается).

 

для работы с периферией используется номер (например номер UART: void usart_set_baudrate (uint32_t usart, uint32_t baud)), а у меня все мои либы используют обычно указатель на хэндл того же UART.

Что, на мой взгляд гораздо прямее, т.к. не нужны никакие if-else по номеру, а сразу usart->sfr.BRR =XX.

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

 

if-else по номеру, а сразу usart->sfr.BRR =XX.
опять же классики учат вначале строить систему максимально правильно(сюда входит и принцип сокрытия информации) а после профилирования устранить узкие места. Если например в коде будет встречаться какой-нибудь uart_send(uint32_t usart, char* string); и эта функция будет дергаться так часто, что упомянутый if-else реально начнет влиять на производительность то например можно будет его упразднить путем добавления функции usart1_send(char* string); где будет прямое обращение к хэндлу порта. Однако же я сомневаюсь что до этого дойдет в данном случае(ибо usart медленный).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Короче в 2016 будет продолжаться ослабление требований к стилям и усиливаться индивидуализация кодирования. То что некоторые называют "говнокодом". Хотя, надо бы банить за применение такого определения.

"Говнокодирование" и "индивидуальный стиль кодирования" это две абсолютно разные вещи. Одна другую не отменяет и не заменяет. Попытки прикрыть говнокодирование разговорами за "индивидуальный стиль" я бы назвал первейшим признаком говнокодера.

 

 

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

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

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

Эта структура по идее вообще должна как можно реже всплывать....

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. книгу М.Фаулера Рефакторинг вы тоже не рекомендуете? А ведь там как раз вполне серьезно вводится понятне code smells и даже проводится аналогия с детскими пеленками кажется ))))

 

Фаулер во-первых пишет про Яву, во-вторых он пишет приложения автоматизации бизнеса, в третьих он пишет, похоже, в том самом notepad-е.

Т.е. с моей точки зрения ссылка на него не в тему.

 

"Говнокодирование" и "индивидуальный стиль кодирования" это две абсолютно разные вещи. Одна другую не отменяет и не заменяет. Попытки прикрыть говнокодирование разговорами за "индивидуальный стиль" я бы назвал первейшим признаком говнокодера.

 

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Любая проблема сначала должна быть четко и однозначно сформулирована. Если проблема заключется в том, что написаное является говном, то это так и надо называть, а не "индивидуальным стилем кодирования". Замена слова "говнокод" эвфемизмами на, например, "код написанный альтернативно одаренным талантом с ярко выраженным индивидуальным стилем кодирования", сути проблемы, увы, не меняет :(.

Говнокод на самом деле может по нынешним временам писаться не только конечным программистом, но и всякими "визардами" или притаскиваться в "библиотеках". Относительно недавно делал рефакторинг говнокода. Те, кто его родил мне знакомы по работе и в общем случае говнокодерами совершенно не являются. Но, одно но. Контроллер был кипарисовский PSoC. C железом там работать тяжело, посему кипарисовцы радостно навязывают использование визарда. Визард генерит великолепно стилистически выверенный говнокод. Дальше выбор, либо лепить из этого говна, либо нет. Из говна конфетку не сделаешь, зато быстро. Сделали быстро. Нет все заработало и работало годами. Только вот количество оборудованя в системе росло, росло и выросло до того, что система стала захлебыватся по пропускной способности канала связи с сервером. Причем канал-то как-бы и достаточный, но есть одна проблема он эфирный, посему сбои, посему на запросы сервера могут и не ответить, посему таймауты. Так вот в таймаутах-то дерьмо в вылилось. Говнокод из говнкогда был сделан так, что ответы на запросы сервера были не самые приоритетные, посему таймауты вынужденно большими. Как только количество оборудования с течением времени увеличили и уровень ошибок возрос, то все и встало колом.

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

Пришлось говнокод чистить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Номер-же порта эта не абстракция а муть бесфоменная - вызов какой-либо функции с номером порта '9' не говорит ни очем.

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

Конечно же и Фаулер и Совершенный Код, Макконнелла, тут тоже не в почете ибо они дескаать сделал карьеру на финансовых системах, а тут всё-же по большей части сидят представители "старой школы", привыкшие считать байты и такты порой даже тогда, когда этого делать не нужно. В то время как я в вышеупомянутых трудах не увидел вредных советов, способных ухудшить код и дизайн эмбеддед системы. Как раз с точностью до наоборот!

 

И абсолютно ясно, что в 2016году пора мыслить в категориях ООП и писать на С++. О чем кстати упоминалось в этой ветке уже.

И что C++ can be as efficient as C это уже не мечты и не легенды, тем кто в теме, тоже ясно.

 

Но если используется номер порта, то добраться до любого эдемента стукруры можно только через пересчет номера порта в адрес этой же структкры.
А я говорю, что добираться до элемента структуры не надо вовсе, а работать с портом надо через интерфейс драйвера UART, который таки да, по номеру порта разберется с чем надо иметь дело и к какому регистру обратиться по запросу GetTXCompleteFlag(UART_9) и выдаст нужный результат. И за UART_9 может стоять хоть целый эзернет и удаленный на 1000км UART, хоть USB-UART переходник - не важно.

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

 

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

 

Я вот исключительно из этих соображений оправдывал абстракцию API драйвера до номера порта. И таки да, я согласен, что если придется сопоставлять номер структуре в рантайме то это вносит некоторый оверхед и использовать регистры напрямую прям в коде это на много меньше лишних телодвижений. И что это меняет? Это отменяет необходимость профилирования и выявления узких мест чтобы вставить костыли ТОЛЬКО туда? НЕТ.

 

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

 

Когда-то я уже приводил тут одну замечательную статью о том, как можно эффективно реализовывать правильные с точки зрения и Фаулера и Макконнела вещи на 8ми битниках и без рантайм оверхеда. Очень советую ознакомиться. http://easyelectronics.ru/rabota-s-portami...erov-na-si.html

Пользуюсь лично и пока не видел лучшего решения поставленной задачи.

Считаю, что это и есть пример того, как нужно программировать в 2016г. Алсо с введением стандартов С++11 и 14 реализация этой библиотеки будет на много проще и компактнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А я говорю, что добираться до элемента структуры не надо вовсе, а работать с портом надо через интерфейс драйвера UART, который таки да, по номеру порта разберется с чем надо

От того, что добираться будет "дравер порта" или кто-то другой в другом месте совершенно ничего не изменится, ибо ДОБИРАТЬСЯ по любому придется. И вопрос в том, что будет

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

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

Ага. Можно постараться и нагородить говнокода для того, что-бы "9" на этапе компиляции вдруг превратилось в, например, указатель на слово флагов. Зачем только?

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

Это у Вас в голове сидит тупой BIOS писишки в котором в 70x годах тупо забили 4 порта, заняли память под 4 структуры даных для этих портов и родили абстракцию "COM1..4" для неведомых приложений.

P.S.

Написал про писишку и понял, что на самом деле есть два РАЗНЫХ взгляда на абстракцию инерефейса.

Один со стороны ЖЕЛЕЗА - есть железка, к нее есть 9 UART, заводим под них массив струкур данных, пишем какие-то функции и все. С точки зрения железячника родившего в меру своего пониманя драйвер для своей железки, это достаточный уровень абстракции.

Второй подход со стороны СИСТЕМЫ, которая вообще изначально ничего ни о каких 9 UART ни на каких конкретных контроллерах не знает и знать не обязана.

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

Так что еще раз, с еще большей уверенностью, повторю - обращение к UART по номерам это на самом деле АНТИабстракция.

 

P.P.S.

У меня лет 20 уже тому назад в одной моей системе системный вызов драйвера предающего фрейм в какой-то COM порт эволюционировал до передачи фрейма _устройству_выполняющему_в системе_заданную_функцию_ вот это уже можно называть абстракцией :).

 

 

 

И, прошу меня извинить, больше я ничего на эту тему писать не буду. Времени жалко :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага. Можно постараться и нагородить говнокода для того, что-бы "9" на этапе компиляции вдруг превратилось в, например, указатель на слово флагов. Зачем только?

то у Вас в голове сидит тупой BIOS писишки в котором в 70x годах тупо забили 4 порта

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

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

Не вижу причин не реализовать драйвер UART на такой-же архитектуре. И Фаулер доволен и байтов лишних не портится.

 

Вот это 2016 год я считаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

×
×
  • Создать...