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

Приоритет операторов в рамках выражений должен быть сделан явным

Описание

Управляйте определением

Приоритет операторов в рамках выражений должен быть сделан явным.

Объяснение

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

Список следующих таблиц определение MISRA C® приоритета оператора для этого правила.

ОписаниеОператор и операндПриоритет
Первичныйидентификатор, постоянный, строковый литерал, (выражение)16
Постфикс[] () (вызов функции) . -> ++ (постинкремент) -- (постдекремент) () {} (C99: составные литералы)15
Унарный++ (постинкремент) -- (постдекремент) & * + - ~ ! sizeof заданный (препроцессор)14
Бросок()13
Мультипликативный* / %12
Дополнение+ -11
Поразрядный сдвиг<< >>10
Реляционный<> <= >=9
Равенство== !=8
Поразрядный AND&7
Поразрядный XOR^6
Битовое "ИЛИ"|5
Логический AND&&4
Логический OR||3
Условное выражение?:2
“()” Присвоение= *= /= += -= <<= >>= &= ^= |=1
Запятая,0

Обменивайтесь сообщениями в отчете

Операнд логического %s не является первичным выражением. Приоритет операторов в рамках выражений должен быть сделан явным.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

развернуть все

int a, b, c, d, x;

void foo(void) {
  x = sizeof a + b;                     /* Non-compliant - MISRA-12.1 */ 
  
  x = a == b ? a : a - b;               /* Non-compliant - MISRA-12.1 */ 

  x = a <<  b + c ;                     /* Non-compliant - MISRA-12.1 */ 

  if (a || b && c) { }                  /* Non-compliant - MISRA-12.1 */ 

  if ( (a>x) && (b>x) || (c>x) )   { }  /* Non-compliant - MISRA-12.1 */ 
}

Этот пример показывает различные нарушения правила 12.1 MISRA®. В каждом нарушении, если вы не знаете порядка операций, код мог бы неожиданно выполниться.

Исправление — разъясняется с круглыми скобками

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

int a, b, c, d, x;

void foo(void) {
  x = sizeof(a) + b;
  
  x = ( a == b ) ? a : ( a - b );

  x = a << ( b + c );

  if ( ( a || b ) && c) { }

  if ( ((a>x) && (b>x)) || (c>x) ) { }
}
# if defined X && X + Y > Z    /* Non-compliant - MISRA-12.1 */ 
# endif

# if ! defined X && defined Y  /* Non-compliant - MISRA-12.1 */ 
# endif

В этом примере два нарушения правила 12.1 MISRA показывают в предварительной обработке кода. В каждом нарушении, если вы не знаете правильного порядка операций, результаты могут быть неожиданными и вызвать проблемы.

Исправление — разъясняется с круглыми скобками

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

# if defined (X) && ( (X + Y) > Z )
# endif

# if ! defined (X) && defined (Y)
# endif
int a, b, c, x;
struct {int a; } s, *ps, *pp[2];

void foo(void) {
  ps = &s

  pp[i]-> a;          /* Compliant - no need to write (pp[i])->a */
  *ps++;              /* Compliant - no need to write *( p++ ) */ 
  
  x = f ( a + b, c ); /* Compliant - no need to write f ( (a+b),c) */
  
  x = a, b;           /* Compliant - parsed as ( x = a ), b */
  
  if (a && b && c ){  /* Compliant - all operators have
                       * the same precedence */
}

В этом примере показанные выражения начинают несколько операций. Однако эти выражения совместимы, потому что приоритет оператора уже ясен.

Проверяйте информацию

Группа: Выражения
Категория: консультация
Категория AGC: консультация
Язык: C90, C99