Я долгое время негодовал по поводу того, что часто приходится копаться в плохо оформленном коде от коллег или в коде из интернета. Но теперь я решил подойти к проблеме с философской точки зрения. Отныне я коллекционирую такие куски нелепого кода. Буду сохранять отдельно все проявления нелепого кода и пополнять парад. Теперь каждая нелепая функция приносит мне радость так, как пополняет ценную коллекцию того, как не надо делать.
Я эти примеры не искал. Это прямо из будничной инспекции программ. Авторы — российские программисты 10+ лет опыта программирования микроконтроллеров каждый.
Итак, код к параду построен!
1—Внутренний корпоративный код стайл обязывает определять константы после определения типов данных! Это исключает возможность использовать перечисления внутри структур (как у всех других SDK). Поэтому перечисления просто тоже запрещены внутренним код стайлом!
//************************************************************************************************** // Definitions of global (public) variables //************************************************************************************************** //! [Description...] DATA_TYPE MODULE_variableZero; //! [Description...] DATA_TYPE MODULE_variableOne; //************************************************************************************************** // Declarations of local (private) data types //************************************************************************************************** //! [Description...] typedef DATA_TYPE MODULE_DATA_TYPE_THREE; //! [Description...] typedef struct { //! [Description of fieldZero...] DATA_TYPE fieldZero; //! [Description of fieldOne...] DATA_TYPE fieldOne; } MODULE_DATA_TYPE_FOUR; //! [Description...] typedef union { //! [Description of fieldZero_struct...] struct { //! [Description of fieldZero...] DATA_TYPE fieldZero; //! [Description of fieldOne...] DATA_TYPE fieldOne; } fieldZero; //! [Description of fieldOne...] DATA_TYPE fieldOne; } MODULE_DATA_TYPE_FIVE; //************************************************************************************************** // Definitions of local (private) constants //************************************************************************************************** //! [Description...] #define MODULE_CONST_TWO (0x01U) //! [Description...] #define MODULE_CONST_THREE (-1) //! [Description...] static const DATA_TYPE MODULE_constFour = 0x02U; //************************************************************************************************** // Definitions of static global (private) variables //**************************************************************************************************
2—Использовать макросы препроцессора вместо перечислений.
//************************************************************************************************** // Definitions of global (public) constants //************************************************************************************************** //! \name CAN frame identifier types //! @{ #define CAN_ID_FORMAT_STANDARD (0U) #define CAN_ID_FORMAT_EXTENDED (1U) //! @} //! \name CAN bus status values //! @{ #define CAN_STATUS_ERROR_ACTIVE (0U) #define CAN_STATUS_ERROR_PASSIVE (1U) #define CAN_STATUS_BUS_OFF (2U) #define CAN_STATUS_SLEEP (3U) //! @}

3—Излишние повторные имена в перечислениях

и структурах

4—Драйвер IRQ, который даже не может активировать или прочитать факт активации конкретного прерывания по номеру в NVIC. IRQ драйвер просто приколочен гвоздями. Там нет базовых функции IRQ_DisableIRQ, IRQ_GetPriority, IRQ_GetVector, IRQ_SetPriority, IRQ_EnableIRQ отдельными функциями, подобно тому, как это сделано в коде CMSIS от ARM. А одной только IRQ_Init() мало.

При этом в драйвере 29k строк кода! Это как?

5—Несостыковка по типам данных

6—Человек вызывает печать в UART из обработчика прерываний. Прерывание, которое генерирует другое прерывание. Здорово!

7—Драйвер чипа W25M02G, который позволяет работать только с одним экземпляром микросхемы SPI NAND Flash памяти (хотя на плате их две!).

8—Статические функции в заголовочном файле. Смысл статических функций как раз в том, чтобы они не вылезали из *.с файла. Человек, который прототипы статических функций сует в *.h не знает основ Си языка.

9—Треугольные функции из вложенных if if if if if if


10—Транслит в названиях функций.

11—Отсутствие имен переменных в определении структуры справа. Если в структуре поменять местами переменные или добавить одну и удалить другую, то всё тихо рухнет в run-time.

12—Нет смысла в битовых полях, если тип совпадает с базовыми типами

13—Несовпадение типов в битовых полях.

14—Невнимательное заполнение битовых полей

15—Очевидные комментарии

16—Отдельная ветка if для нулевого значения, когда нулевое значение может и обработать формула

17—Перечисления маленькими буквами. Как и всякие константы, экземпляры перечислений тоже лучше прописывать заглавными буквами. Чтобы не путать с переменными.

18- Не надо делать таблицу в перечислении. Если это линейная функция, то её следует вычислять по формуле.

Вывод
Как видно, к нелепостям приводит CopyPaste-программирование, ментальная лень, банальная невнимательность и глупая блажь в регламенте code style 10-ти летней давности. Не делайте так.
Присылайте в комментариях примеры нелепого кода, который встретили Вы. Мне просто интересны границы возможного абсурда.
Ссылки
|
№ |
Название |
URL |
|
1 |
Потёмкинская Деревня в Коде |
|
|
2 |
Атрибуты Хорошего С-кода |
|
|
3 |
КодоГенератор Линейных Отображений (как ускорить создание ASIC драйвера) |
ссылка на оригинал статьи https://habr.com/ru/articles/718300/
Добавить комментарий