exponenta event banner

MISRA C:2012 Правило 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 */ 
}

В этом примере показаны различные нарушения правила 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 */
	}
}

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

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

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