MISRA C:2012 Rule 12.1

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

Описание

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

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

Объяснение

Язык 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

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

Коррекция — разъясняется с круглыми скобками

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

# if defined (X) && ( (X + Y) > Z )
# endif
int a, b, c, x,i = 0;
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: консультация