Код должен быть записан таким образом, чтобы он имел определенные желаемые свойства (критерии качества). Некоторые критерии качества практически всегда желательны, такие как правильность, удобочитаемость, ремонтопригодность (даже здесь есть исключения, например, если вы вводите код для запутанного конкурса c или underhanded c contest). Другие критерии качества применимы только для определенных проектов или организаций, например переносимости для 16-разрядных машин.
Хорошо сформулированное правило кодирования обычно поддерживает один или несколько критериев качества. Однако это может противоречить другим. Существует большое количество установленных правил кодирования, которые поддерживают типично желаемые критерии качества, но без значительного негативного воздействия на других. Многие из них были идентифицированы довольно давно (Kernighan and Plauger: Elements of Programming Style, 1974, и, да, у меня есть его копия :-). Порой идентифицируются дополнительные хорошие правила.
Если в очень редких случаях (например, умышленном обфускации) код должен следовать этим «установленным хорошим правилам», не имеет значения, являются ли они частью MISRA-XXXX или нет. И, если будет найдено новое хорошее правило, убедитесь, что люди начинают следовать за ним. Вы даже можете принять решение применить это новое правильное правило к уже существующему коду, но это скорее решение руководства из-за риска.
Просто не имеет смысла не следовать правильному правилу только потому, что он не является частью MISRA-XXXX. Точно так же не имеет смысла следовать плохому правилу только потому, что он является частью MISRA-XXXX. (В MISRA-C-2004 говорится, что они удалили 16 правил из MISRA-1998, потому что «у них не было смысла» - надеюсь, некоторые разработчики заметили и не применяли их. И, как упоминает Лундин, в MISRA-2012 снова некоторые «странные правила» были удалены).
Однако имейте в виду, что для почти каждого правила его бездумное приложение может в определенных ситуациях даже ухудшать критерии качества, которые он обычно поддерживает.
В дополнение к тем общепринятым правилам существуют правила, которые имеют отношение только к конкретным критериям качества для вашего кода. Что усложняет ситуацию, так это то, что в большинстве проектов для разных частей кода различные критерии качества имеют разную значимость.
- Для работы службы прерываний более критичной, чем для большинства других частей программного обеспечения. Поэтому компромиссы по другие критерии качества будут сделаны.
- Некоторые части программного обеспечения предназначены для переносимости между средами, но часто путем введения адаптеров/оберток, которые затем являются специфическими для определенной среды. Таким образом, сам адаптер не предназначен для переноски.
За исключением вышеупомянутых «установленных хороших правил», фиксированный набор правил кодирования, следовательно, не может хорошо работать для всех частей типичного программного обеспечения. Итак, для каждой части программного обеспечения сначала определите, какие критерии качества релевантны для этой части. Затем примените те шаблоны, принципы и правила, которые действительно поддерживают эти конкретные критерии качества соответствующим образом.
Но как насчет MISRA? Правила MISRA предназначены для поддержки критериев качества, таких как правильность посредством анализируемости (например, запрет рекурсии и управления динамической памятью), переносимость (например, выделение кода сборки). То есть для частей программного обеспечения, где эти конкретные критерии качества не имеют отношения к делу, соответствующие правила MISRA не приносят никакой пользы. К сожалению, MISRA не имеет понятия архитектуры программного обеспечения, где разные части имеют разные критерии качества.
Хотя многие правила улучшились по сравнению с релизами MISRA, существует еще много правил, которые более строгие, чем необходимо (например, «no/* внутри // комментарии и наоборот» - почему?) И правила, которые пытаются избежать (маловероятные) ошибки, которые могут ввести проблемы, а не решать их (например, «повторное использование какого-либо имени, даже в разных локальных областях»). Вот мой совет для вас: если вы a) действительно хотите, чтобы ваш контролер правил обнаружил все ошибки и b) не возражайте, чтобы получить абсурдное количество предупреждений с высоким коэффициентом ложноположительного отношения, это одно правило/checker делает все это для вы: «предупреждение: обнаружена строка кода: < строка кода>».
И, наконец, MISRA разрабатывается в предположении, что C (в частности, его арифметика) слишком сложно понять. MISRA разрабатывает собственную арифметику на вершине C, полагая, что разработчики вместо этого должны изучать арифметику MISRA, а затем могут уйти без понимания C-арифметики. По-видимому, это не удалось, потому что модель MISRA-2004 («базовый тип») была заменена другой («основной тип») в MISRA-2012. Таким образом, если ваша команда хорошо понимает C и использует хороший инструмент статического анализа (или даже несколько), который способен идентифицировать проблемные сценарии с арифметикой C, подход MISRA, скорее всего, не для вас.
TL; DR: соблюдать стандартные рекомендации, применять установленные хорошие правила. Определите конкретные критерии качества для разных частей вашей архитектуры. Для каждой части примените шаблоны, принципы и правила, соответствующие этой части. Понимание правил перед их применением. Не применяйте глупые правила. Используйте хороший статический анализ кода. Убедитесь, что ваша команда понимает C.