Пролог

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

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

1. Запрет установки программ, запрет открытия диспетчера устройств, запрет открытия диспетчера задач, запрет прописывания переменной PATH на локальных PC. Всё только через пароль руководителя отдела.

2. Собирать код только мышкой из-под GUI-IDE (IAR или KEIL) и никаких там скриптов сборки (Make, CMake)!

3. Строгие правила расставления отступов к коде и вообще искусственно выдуманное форматирование кода, которое даже опциями clang-format или GNU-indent выставить невозможно. Только ручное расставление отступов!

4. Строгие правила оформления шапки текста перед каждой функцией. Не дай бог поставишь лишний пробел!

5. Писать текстовые комментарии к каждой строчке Си-кода. Не важно, что по именам переменных и функций и так всё ясно.

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

7. Строжайший запрет на использование объединений (union) в программах Си .

8. Строжайший запрет на использование перечислений (enum) в языке программирования Си.

9. Каждая конфигурационная константа должна иметь комментарий с "Valid values", в котором описано множество возможных значений данной константы. Перечисления (enum) же запрещены, поэтому надо как-то выкручиваться, через эти текстовые комментарии.

10. Запрет на использование стандартных типов данных из файлов <stdint.h> <stdbool.h> (bool, uint32_t, int8_t и проч.)

11. Первая строка файла должна содержать комментарий "start of file"

12. Предпоследняя строка исходного файла должна содержать комментарий

"//****end of file*******"

Как мне сказал автор требования: "Это чтобы посылать код сообщением в текстовом мессенджере и чтобы было понятно, где заканчивается файл". Как вам такая аргументация?

13. Настройки компоновщика хранить прямо в папке с проектом. И так для каждого проекта с одним и тем же микроконтроллером. Получается дублирование конфигов для компоновщика.

14. Использование кода сторонних библиотек запрещено! Никакого FreeRTOS, CMSIS, FatFs, HAL от официального производителя микроконтроллера! Любое Third Party запрещено!

15. Все аргументы функций должны быть перечислены "в столбик".

16. Для всех объявлений глобальных функций в h-файле обязательно ключевое слово extern! Не важно, что и без extern код собирается и работает.

17. Порядок объявления функций должен совпадать с порядком определения функций. Просто лишнее правило, чтобы время больше потратить.

18. Все комментарии должны начинаться с //~ и никак иначе!

Мы выдумаем свой фирменный стиль для однострочных комментариев. Так мы продвигаем свой бренд.

19. Запрет на многострочные комментарии /**/

20. Строжайший запрет на использование функций из <math.h> [sin() cos() log10() fabs() и т. п.]!

21. Рядом с глобальными переменными писать комментарием: "Смотрите, это глобальные переменные!"

22. В верху си-файла писать название файла комментарием. Не важно, что это и так видно в файловой системе. А потом еще следить, чтобы всегда совпадало. Везде.

23. В конце каждой функции писать комментарий: "смотрите, это конец функции!" А то ведь по фигурной скобке не ясно...

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

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

Думаю не надо пояснять, что такая мартышкина бюрократия лишь только тормозит достижение реального функционального результата по разработке system software.

При этом, добавлю, что в таких щепетильно "требовательных" организациях, как правило, не принято собирать проекты из скриптов, покрывать код модульными тестами, в прошивках нет NVRAM, в прошивках отсутствует UART-CLI для отладки функционала, нет и сервера сборки, никакого даже в Jenkins, в прошивках нет загрузчика и многого того, что, по здравому смыслу вообще-то должно, быть сделано как раз в первую очередь... Понимаете?...

Порой всё это законотворчество выглядит, как соблюдать правила хирургической стерильности, в конюшне! Да.. Именно так... Чрезмерные требования к оформлению кода похоже на какую-то армейскую IT-муштру.

Итоги

Вот объясните мне, пожалуйста, в чем глубинный смысл упомянутых выше требований к коду?

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

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

На самом деле это даже здорово придумывать всё новые и новые требования к code style. Так можно аргументировать раздувание фронта работ начальству, что тебе и коллегам гарантирована оплачиваемая работа на обозримую перспективу. Можно годами как пиявка высасывать из компании зарплату за то, что с меньшими требованиями к code style можно сделать максимум за 2-3 месяца.

Правда в том, что каждое требование к коду сдвигает срок сдачи программного проекта на 10-15%. Когда в организации, например, 463 правила оформления Си-кода, то время разработки увеличивается в 46,3 раз. Понимаете?

Скажите мне, смог бы солдат Курчатов Игорь Васильевич сделать атомную бомбу с нуля за 4 года с такой вот бюрократией? Думаю ответ и так всем понятен...

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

Ссылки

Комментарии (27)


  1. Tzimie
    21.08.2024 16:33
    +4

    А зачем вы там работаете?


    1. aabzel Автор
      21.08.2024 16:33
      +1

      Может у меня симпатия к продукту, который разрабатывает организация.


  1. qiper
    21.08.2024 16:33
    +2

    1—
    ...
    5--
    ...
    13 --

    Код также оформляете?)


  1. ripandtear
    21.08.2024 16:33
    +2

    Хмм, мой 10-летний опыт работы в embedded говорит о том, что довольно часто на программистов скидывают какой-то проект, и люди изолированно его пилят. Вообще почти никогда никому не интересно, что там внутри под капотом. Очень такое любят в совдепо-подобных компаниях на 50 человек (Я в таких бывало когда-то давно работал)

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

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


    1. aabzel Автор
      21.08.2024 16:33
      +1

      Да. Работа программистом-микроконтроллеров в российских военных НИИ хороша тем, что начальство, как правило, тебе не мешает.

      Там начальство это в прошлом схемотехники, конструкторы, чертёжники, кто угодно но только не программисты и оно понимает, что ничего в Си-программировании не понимает и просто предпочитает не мешать программистам-микроконтроллеров работать.

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

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

      Один минус. Зарплаты там низкие.


  1. powerman
    21.08.2024 16:33
    +3

    Если представить себе начальника совсем уж старой школы (лет 60+), который:

    • не хочет изучать то, что не знает (проще запретить использовать "лишний" функционал)

    • когда-то давно наступил на какие-то грабли (с тем же make или какой-нибудь несовместимостью в math.h) и нашёл обходное решение, которое теперь требует чтобы все его использовали

    • привык печатать исходники программ и изучать их с бумаги (отсюда требование писать название файла в первом комментарии)

    • соблюдать максимально строгие требования органов безопасности к сертификации кода (отсюда запрет использовать сторонние опенсорсные зависимости)

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

    • ...

    • и в целом привык работать скорее по гос.заказам нежели в стартапе

    то никакого удивления эти правила не вызовут.

    Единственная верная реакция в этой ситуации - "голосовать ногами".


    1. olku
      21.08.2024 16:33
      +3

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


  1. ChePeter
    21.08.2024 16:33

    После школы21 эти все пункты просто детский сад.


    1. aabzel Автор
      21.08.2024 16:33

      А что в школе21 есть ещё более нелепые требования?


  1. MountainGoat
    21.08.2024 16:33
    +1

    Показывали мне давно на Реддите такую схему. У классов-микросервисов где-то в середине среди комментариев - такая строчка: //[150 пробелов]&$--

    Так вот: по этой строке скрипт CD определяет IP и credentials какой отладочной базы данных подставить при деплое. Догадываетесь зачем там 150 пробелов? Чтобы не было лишних вопросов. И главное: если этот комментарий отсутствует или неправильно парсится, то подключается - та-дам! боевой прод.

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


  1. dataerased
    21.08.2024 16:33
    +1

    Выглядит так, что имеете дело с военной приёмкой.

    Запрет 3rdparty - чтоб левых уязвимостей не занесли (как-то так мне когда-то аргументировали).

    Странные требования к форматированию - чтоб исходники в папочке хранить, и формат не отличался от тех что с 80х годов хранятся.


  1. Serpentine
    21.08.2024 16:33

    Если я правильно понимаю, то ГОСТ Р 51904-2002 "Программное обеспечение встроенных систем. Общие требования к разработке и документированию" таки предусматривает, что исходный код может быть напечатан на бумаге (в отдельных случаях), отсюда и требования к шапкам определенной длины и т.п.

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

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


    1. aabzel Автор
      21.08.2024 16:33

      Если я правильно понимаю, то ГОСТ Р 51904-2002 "Программное обеспечение встроенных систем. Общие требования к разработке и документированию" таки предусматривает, что исходный код может быть напечатан на бумаге (в отдельных случаях), отсюда и требования к шапкам определенной длины и т.п.

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

      Проблема в том что 60%...80% российских программистов-микроконтроллеров (даже возрастом 40+) не умеют пользоваться скриптами (никакими), так как из GUI-IDE никогда не вылазили.


      1. Serpentine
        21.08.2024 16:33

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

        Речь ведь шла про шапки над функциями (4), а не только про начало/конец файла. Вы недооцениваете упоротость бюрократов. Они могут сверить исходники с распечаткой и увидеть несоответствие, и никого не будет интересовать что компилятор комментарии игнорирует.

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


  1. kenomimi
    21.08.2024 16:33
    +3

    14. Использование кода сторонних библиотек запрещено! Никакого FreeRTOS, CMSIS, FatFs, HAL от официального производителя микроконтроллера! Любое Third Party запрещено!

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

    13. Настройки компоновщика хранить прямо в папке с проектом. И так для каждого проекта с одним и тем же микроконтроллером. Получается дублирование конфигов для компоновщика.

    А лучше делать лапшу инклудов, когда 9000 чипов на 100500 проектов, и понеслось - громадный write-only скрпт сборки, и не менее нечитаемый .ld-файл, где чёрт ногу сломит... Еще лучше тянуть откуда-то его - в одном проекте поменяли файл без предупреждения - легла вся сборка, и сиди разбирайся. Имхо, как раз красиво класть законченый файл под каждый контроллер в каждый проект - пофиг на дублирование, эра дискет прошла. С массовыми правками неудобно, но они настолько редки, что принимать их во внимание смыла не имеет.

    15. Все аргументы функций должны быть перечислены "в столбик".

    Когда их много, больше 5-7, то правило абсолютно верное, ибо эта строка даже в 4к монитор не всегда влезает :)

    Остальное какая-то лютая дичь.


    1. aabzel Автор
      21.08.2024 16:33

      как раз красиво класть законченный файл под каждый контроллер в каждый проект - пофиг на дублирование

      Надо чтобы в репозитории была папка для каждого микроконтроллера с которым происходит работа (или семейства). Там и хранить настройки компоновщика.

      В этом случае несколько сборок смогут унаследовать один и тот же файл настройки компоновщика.

      Исправления в одном месте раскатятся сразу на все нужные проекты.

      Код надо строить иерархично.


    1. aabzel Автор
      21.08.2024 16:33

      Когда их много, больше 5-7, то правило абсолютно верное, ибо эта строка даже в 4к монитор не всегда влезает :)

      Дело в том что clang-format не может принудительно расставить в столбик все аргументы везде. clang-format это делает только если не помещается в разрешенную ширину строку.


  1. victor_1212
    21.08.2024 16:33
    +1

    для real time обычное дело, чем сложнее система тем больше требований, если активно работает 30-50 человек над проектом, неизбежно будут разные стили, как-то надо причесывать все это, главное чтобы max читабельно было, иначе совместную работу трудно вести, самый приятный код, который приходилось видеть был burroughs mcp много лет назад


    1. aabzel Автор
      21.08.2024 16:33

      Да, но надо меру знать. 20-50 требований ещё норм, но 400+ это перебор.

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


      1. victor_1212
        21.08.2024 16:33
        +1

        400+ перебор ...

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


        1. aabzel Автор
          21.08.2024 16:33

          На самом деле это даже здорово придумывать всё новые и новые требования к code style. Так можно аргументировать раздувание фронта работ начальству, что тебе и коллегам гарантирована оплачиваемая работа на обозримую перспективу. Можно годами как пиявка высасывать из компании зарплату за то, что с меньшими требованиями к code style можно сделать максимум за 2-3 месяца.


          1. randomsimplenumber
            21.08.2024 16:33

            Начальство все понимает и одобряет.

            можно сделать максимум за 2-3 месяца

            Но не нужно.


  1. atues
    21.08.2024 16:33
    +4

    Мне как-то достался проект ( java), который нужно было немного допилить под изменившиеся требования. В нем идентификаторы были написаны на иврите, но латиницей (все равно, что написать русское слово "счетчик" как "schetchik"). Конечно, не зная иврита понять, что означают эти идентификаторы можно было только из контекста. Но это оказалось мелочью. Я долго не мог понять, откуда считываются параметры конфигурации при запуске. Оказалось, что конфиги были в комментариях в самих исходниках. Т.е.при запуске скомпилированной программы, нужно было тут же рядышком держать и исходники. Иначе, программа ругалась на то, что нет файлов конфигурации. Т.е. программа при запуске парсила свои же исходники и вычитывала из комментариев свою же конфигурацию. Какая-то извращенная сволочь это придумала.

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

    А вы о каких-то стилях оформления кода толкуете :)))


    1. mihmig
      21.08.2024 16:33
      +6

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


  1. randomsimplenumber
    21.08.2024 16:33
    +1

    Вспомнился анекдот про обезьян, у которых так принято.


  1. Indemsys
    21.08.2024 16:33
    +1

    В принципе большинство правил правильные.
    Остальные, подозреваю, взяты из другой организации или придуманы автором чтобы разогреть тему.
    Битовые поля, юнионы и перечисления стараюсь не использовать. И это потому что что они мешают отладке. Вообще все языковые конструкции что мешают отладке идут побоку.
    Отладка важнее удобства и всякого синтаксического сахара.
    Попадись мне автор в сотрудники я бы ему еще правил накидал.
    Например, запретил бы писать несколько операторов в одну строку (потому что неудобно ставить брекпоинты). Все if тоже запретил бы писать без скобок (про той же причине). Запретил бы макросы с вычислениями (потому что отладчик не заходит в макросы и там нельзя проставить брекпоинт). Запретил бы тернарные операторы (опять из-за брекпоинтов ). Запретил бы большие буквы в переменных (потому что так принято в уважаемых сторонних проектах ). Заголовки функций, да должны быть по шаблону. (потому что память подводит, а что делает функция надо быстро вспомнить, а нормальные редакторы шапку формирую автоматом).
    Да, комментарии везде ставлю такие //, это, во-первых, чтобы не лазить мышкой в конец текстового блока чтобы написать */ , а во-вторых комментарии типа // лучше выделяются в тексте при отладке, где может быть не виден конец комментария из-за узкого окна.

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

    Тут недавно столкнулся с сорсами от Infineon. Там во всех условиях в конструкциях if сначала стоит константа, а потом переменная. Досталось видимо с той эпохи динозавров, когда == могли спутать с = . Но раздражает дико. Не поленился и в их либах везде исправил, потому что эти сорсы предстояло отлаживать. А в процессе отладки ничего не должно раздражать.


    1. aabzel Автор
      21.08.2024 16:33

      И это потому что что они мешают отладке. 

      Вы что, код только через пошаговую GDB отладку только отлаживаете что-ли?