MISRA C

MISRA — это Motor Industry Software Reliability Association группа разработавшая стандарт языка Си для ответственных встраиваемых систем. Для таких как автомобильная или авиационная техника, разных опасных производств. Где цена программной ошибки может быть очень высока. Это набор ужесточающих правил для языка Си. Есть версия и для С++, но не суть. Вся прелесть в том, что MISRA C поддерживается некоторыми компиляторами и если добавить соответствующие ключи, то они будут проверять код еще и на соответствие MISRA C, например IAR. Есть и отдельные анализаторы кода на соответствие стандарту.

Ну, а сама суть стандарта в том, чтобы осложнить жизнь разным быдлокодерам и любителям красиво повыебываться в коде :) Там, например, запрещено пихать в заголовок for все кроме стандартных опций жизнеобеспечения цикла. Запрещены стандартные типы вроде char или int которые зависят от архитектуры. Только жестко описанные типы вроде uint8_t. Запрещены switch без default, а case и if/else без заключения содержимого в { } блоки. Запрещена указательная арифметика и все в таком духе. Таких правил там штук под двести. Настоящий концлагерь для кодера, где ничего нельзя :) Зато сделать тупую ошибку становится сложней.

Так вот, к чему я. Недавно наткнулся на хороший перевод правил MISRA C для IAR. От Андрея Шлеенкова. Вот, делюсь :)

22 thoughts on “MISRA C”

  1. А я уж было с первых строк подумал, что далее будет описано как таки можно умудриться этот MISRA C обмануть и напихать в код тупых ошибок :-) А так конечно оно занятно, да.

      1. Хватает конечно :-) Однако иногда душа требует чего-то нового :-)
        «Мсье знает толк в извращениях…» (с) не помню откуда

        P.S. Шутка конечно.

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

        Это как скальпель.Хирургу — сильно помогает. Схемотехнику тоже (хоть и используется не по назначению). А вот домохозяйка с его помощью тоже может картошку почистить и мяско порезать, но вот довольна им скорее всего не останется.

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

  2. MISRA — хороший сборник правил, но не стоит пользоваться им бездумно. Для начала, пользуясь MISRA в принципе невозможно написать ни одной программы: int — запрещен, а стандарт требует «int main(…)» и ничего другого.

      1. Ага — ISO/IEC 9899:201x (C11) 5.1.2.2.1:
        «It shall be defined with a return type of int and with no parameters … or with two parameters»
        Ну и, как минимум некоторые, компиляторы это проверяют.

            1. Какой перенос проблемы? Проблема динамической памяти в том, что она может утечь, у нас могут данные перемешаться. НА статической памяти у всего свои адреса и если не хватит буфера, то это будет проблемой только тсп/ип, а не всей системы.

                  1. Нашел такой комментарий. Кажется разумным.

                    > As we all know, one of the MISRA C rule discourages the use of malloc for dynamic memory allocation.
                    There are too many variables:
                    — where it get memory from
                    — how blocks are allocated
                    — how blocks are freed
                    — how fragmentation is dealt with
                    — is it even thread safe

                    I’ve seen one malloc/free in the past, where if you freed memory in the «wrong» order, then it would take 1000’s of times longer to free the memory than if you freed it in the «right» order.
                    This kind of random behaviour is something you don’t want in an embedded system.

                    You start with something like
                    char pool[1000000];
                    and you write myMalloc etc yourself.

                    There are all sorts of strategies you can take when you’re tailoring the solution to a particular problem (eg. using a pool approach where only fixed sized blocks are used).
                    Allocating and freeing may waste a bit of memory, but they become very deterministic.

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

                    Хотелось бы все-же знать, что имелось ввиду под этим правилом…

                    1. У динамического выделения памяти две основные проблемы — фрагментация и overbooking (т.е. что делать, если памяти в какой-то момент не хватило). Ну и еще пара по-мелочи.

  3. Да всё там нормально. Можно писать рабочий код без проблем. Часто выключаются проверки на определённые вещи типа указателей или при прямой работе с железом.. А вообще код получается очень даже читаемый.. Я писал софт для модулей в автомобили на RH850 b greenhills компилятору..

  4. Такой стандарт, что аж полтора компилятора умеют…

    А вообще-то очень странно ограничивать использование возможностей С, прописаных в стандарте. Тогда уж и прерываниями не пользоваться, ибо сильно зависят от архитектуры. Вместо запрета адресной арифметики нужно просто советовать перейти на Java, там чуваки вообще не знают что такое указатель.

    1. Да? А как ты запихнешь программу с виртуалкой в ограниченный объем?
      А потом ты будешь управлять машиной, жать на тормоз, а она тебе: «Нет! Мусор собирается.»
      Вот удивляют такие комментаторы, в проблеме не разберутся и лезут с критикой «нафига, пачему, зачем»
      Надо потому что.

Добавить комментарий

Ваш e-mail не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.