Соответствие MISRA: 2020, которое объединяет и разъясняет множество руководств, которые ранее были рассредоточены по публикациям руководств по кодированию MISRA C и C++, содержит список правил и руководств MISRA.

Чтобы узнать больше об основах MISRA, нажмите это, чтобы прочитать другую историю о MISRA 101…

Нарушения и дефекты

В MISRA-C:2012 содержится 143 правила и 16 «директив» (то есть положений, соблюдение которых является более двусмысленным или относится к процессу или процедурным вопросам), каждое из которых классифицируется как обязательное, обязательное или рекомендательное. Они делятся на две категории: единая единица перевода и система. Правила далее подразделяются на категории «Решаемые» и «Неразрешимые».

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

«Дефекты больше похожи на предупреждения независимого кода, исходящие от компиляторов C, такие как затенение переменных, запись без дальнейшего чтения и т. д.»

Подход

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

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

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

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

Пора приближаться!

Давайте перейдем к некоторым нарушениям

MISRA C:2012 Правило 2.3

"Если тип объявлен, но не используется, то рецензенту неясно, является ли этот тип избыточным или он был оставлен неиспользованным по ошибке".

int16_t unusedtype ( void ) { 
typedef int16_t local_Type; /* Non-compliant */ 
return 61; 
}

Ну, я слышу, как вы говорите: «Это слишком просто». Давайте рассмотрим более сложную задачу.

MISRA C:2012 Правило 14.4

"Управляющее выражение оператора if и управляющее выражение оператора итерации должны иметь по существу логический тип".

#include <stdbool.h>
#include <stdlib.h>

#define TRUE 1
typedef _Bool bool_t;
extern bool_t flag;
int a;
uint32_t i;
float b;
void doesntmatter(void){
    while(TRUE){}             /* Compliant */

    while(flag){}             /* Compliant */

    if(b){}                   /* Non-compliant - int is not boolean */

    if(a != 0){}              /* Compliant */

    for(int i=-10; i;i++){}   /* Non-compliant - int is not boolean */

    for(int i=0; i<10;i++){}  /* Compliant */
}

Если вы столкнулись с этим нарушением, вы должны просто проверить, является ли управляющее выражение логическим или нет. Проверьте наличие typedef и extern, если вы используете стандартные библиотеки.

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

MISRA C:2012 Правило 10.8

"Значение составного выражения не должно быть приведено к другой категории основного типа или более широкому основному типу".

Я гарантирую, что вы решите десятки существенных ошибок типа. 10.8 — одно из сложных правил.

typedef int uint32_t;
float fl;
uint32_t sum;
sum = (uint32_t)((fl + 100f)/(50f);        //Non-Compliant
sum = (uint32_t)((float)(fl + 100f)/(50f); //Compliant

Мы приводим его два раза, потому что правило говорит нам не приводить составное выражение, и мы обманываем его, приводя «приведенное» выражение. Я называю это двойным броском :).

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

MISRA C:2012 Правило 6.1

«Битовые поля должны быть объявлены только с соответствующим типом».

int     b:3;    // Noncompliant - may have the range of values 0..7 or -4..3
float   c:3.0f; // Noncompliant - both type and values are not fit
_Bool   d:true; // Compliant
uint8_t e:5;    // Noncompliant - may have the range of values 0..11 or -6..5
uint8_t f:1;    // Compliant

По сути, существуют соответствующие типы для определений битовых полей, объявлений и операций. Битовое поле должно иметь тип, который является квалифицированной или неквалифицированной версией _Bool, signed int, unsigned int или какой-либо другой реализацией. определенный тип

Правило 20.7 MISRA C:2012

«Выражения, полученные в результате раскрытия макропараметров, должны быть заключены в круглые скобки».

Допустим, это наш заголовок «types».

#ifndef INC_TYPES_H_
#define INC_TYPES_H_

#define RBIT01(P) (P >> 1u)
#define RBIT02(P) (P >> 2u)
...

#define LBIT01(P) (P << 1u)
#define LBIT02(P) ((P) << 2u)  //P is in parentheses
...
#endif

#include "types.h"

uint8_t eightbits = 0xA5;

RBIT01(eightbits);             // Noncompliant
RBIT02(eightbits);             // Noncompliant
LBIT01((eightbits));           // Compliant
LBIT02(eightbits);             // Compliant because P is in parentheses in decleration
LBIT01(RBIT02(eightbits));     // Noncompliant
RBIT01((RBIT02((eightbits)))); // Compliant

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

Заботиться. Код безопаснее!