MISRA-C:2012 имеет 3 категории, по которым сортируются все директивы и правила:
- Обязательный. Вы должны следовать им, и вам не разрешается делать отклонения.
- Необходимый. Вы должны следовать им, но вам разрешено нарушать их, если вы заявляете о формальном отклонении от правила. Вам нужна веская причина, почему.
- Консультативный. Рекомендуется следовать им, но вы можете нарушать их, не вызывая формального отклонения (хотя рекомендуется поднимать отклонение).
Идея, лежащая в основе отклонений, заключается в том, что в вашей компании должна быть рутина для их устранения, например, внутреннее поручение по обеспечению качества или что-то, что можно поднять на собраниях по проверке кода и т. д. Идея состоит в том, что кто-то еще, кроме вас, должен быть вовлечен в процесс создания отклонение, предпочтительно кто-то с обширными знаниями C. Это описано в MISRA-C 5.4, а также в дополнительном руководящем документе под названием Соответствие MISRA: 2016 может оказаться полезным.
Мой личный совет, как реализовывать отклонения, — не допускать их вообще в каждом конкретном случае. Вместо этого следует разработать отдельный документ стандарта кодирования для компании — вам все равно нужен какой-то документ, чтобы заявить о соответствии MISRA. Этот документ должен содержать список всех отклонений в масштабах всей компании. Если есть необходимость отклониться, общекорпоративный документ должен быть обновлен. Это на самом деле избавляет вас от внедрения множества бюрократических процедур и избавляет вас от различных менее опытных программистов, выдвигающих странные идеи только потому, что они не понимают обоснования правила MISRA-C.
Что касается одного оператора возврата для каждой функции, то, на мой взгляд, это известный дефект в MISRA-C, унаследованный от IEC 61508 ( Я думаю, что я единственный, кто действительно удосужился исследовать, откуда исходит требование). Вы должны выдвигать постоянное отклонение от правила, так как это ерунда. Лично я перефразировал требование как «функции не должны иметь более одного оператора возврата, если только несколько операторов возврата не приводят к более читаемому коду». Это охватывает то, что, как мы надеемся, было истинным намерением правила, а именно избежать программирования спагетти.
MISRA принимает только функции, у которых есть прототип, даже для статических. Это позволяет программисту размещать свои функции в любом месте файла независимо от порядка вызова. Без прототипа основная функция должна быть самой последней функцией в файле, а многофункциональная рекурсия невозможна, потому что функция может вызывать только ту, которая объявлена выше.
Я не верю, что это имеет какой-то смысл, похоже, вы пытаетесь решить проблему, которой не существует. Вам следует избегать случайной рекурсии, 1) зная, что вы делаете, и 2) используя инструменты статического анализа, как того требует MISRA.
Если вы хотите, чтобы стек вызовов был func1() -> func2() -> func3() и блокировал func2() или func3() от вызова func1(), это лучше всего решить с помощью надлежащего дизайна программы. Давая функциям интуитивно понятные имена и руководствуясь здравым смыслом, вы очень далеко продвинетесь.
Если этого недостаточно, вы можете разделить единицу перевода на две части и создать отдельную пару файлов h/c для внутренних компонентов. Риск, который вы описываете, в основном представляет собой проблему, если у вас есть очень длинные исходные файлы с множеством функций в них, до такой степени, что программист теряет их из виду. Это также является хорошим признаком того, что файл (и/или функции) следует разделить на несколько частей.
Что касается обоснования этого правила MISRA, то оно очень здравое, а именно: блокировать старое дерьмо C90 от «изобретения» соглашения о вызовах (неявный тип возвращаемого значения int, создание параметров и т. д.) только потому, что компилятор не может найти прототип функции. Вы точно не должны отступать от этого правила.
person
Lundin
schedule
04.10.2017