MISRA C:2012 Rule 12.1

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

Описание

Определение правила

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

Объяснение

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

В следующей таблице перечислены MISRA C® определение приоритета оператора для этого правила.

ОписаниеОператор и операндПриоритет
Предварительные выборыидентификатор, константа, строковый литерал, (выражение)16
Постфикс[] () (вызов функции) . -> ++(после постшага) --(после сокращения) () {}(C99: составные литералы)15
Одноместный

++(предварительный шаг) --(предварительное сокращение) & * + - ~ ! sizeof _Alignof defined (препроцессор)

14
Бросок()13
Мультипликативный* / %12
Добавка+ -11
Битовый сдвиг<< >>10
Относительный<> <= >=9
Равенство== !=8
Побитовые И&7
Битовый XOR^6
Побитовое ИЛИ|5
Логический И&&4
Логический ИЛИ||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 */ 
}

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

Коррекция - Уточнение круглыми скобками

Чтобы соответствовать этому правилу 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 */
	}
}

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

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

Группа: Выражения
Категория: Консультационные
Категория СМЖЛ: Консультационная