メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

MISRA C:2012 Rule 12.1

The precedence of operators within expressions should be made explicit

説明

ルール定義

The precedence of operators within expressions should be made explicit 1 .

根拠

C 言語には多数の演算子があり、その優先順位は直感的ではありません。経験の浅いプログラマは容易にミスを犯す可能性があります。かっこを使い、明示的に演算子の優先順位を定義してあいまいさを排除します。

以下の表では MISRA C™ でのこのルールに対する演算子の優先順位の定義をまとめています。

説明演算子とオペランド優先順位
最優先識別子、定数、文字列リテラル、(式)16
接尾辞[] () (関数呼び出し) . -> ++ (後置インクリメント) -- (後置デクリメント) () {} (C99: 複合リテラル)15
単項

++ (前置インクリメント) -- (前置デクリメント) & * + - ~ ! sizeof _Alignof defined (プリプロセッサ)

14
キャスト()13
乗算* / %12
加算+ -11
ビット単位シフト<< >>10
関係<> <= >=9
等号== !=8
ビット単位 AND&7
ビット単位 XOR^6
ビット単位 OR|5
論理 AND&&4
論理 OR||3
条件?:2
代入= *= /= += -= <<= >>= &= ^= |=1
コンマ,0

式の優先順位は、式の解析ツリーの 'ルート' 要素の優先順位です。つまり、式の優先順位は、式で最後に実行される演算の優先順位です。たとえば、次の式を考えてみましょう。

a - b << c + d
この式のルート演算子は << であり、その優先順位は 10 です。オペランド a - b および c + d のランクは 11 です。

式とその部分式の優先順位の使用について、MISRA C:2012 規約では次のことを推奨しています。

  • sizeof 演算子のオペランドをかっこで囲む。

  • 以下のすべての条件に該当する場合は、式のオペランドをかっこで囲む。

    • オペランドの優先順位が 13 未満である。

    • オペランドの優先順位が式の優先順位よりも高い。

    • 式自体の優先順位が 2 から 12 の範囲内である。

Polyspace 実装

ルール チェッカーは、以下の条件が 1 つでも満たされた場合に、違反を報告します。

  • 式のオペランドの優先順位が式のルート演算子の優先順位よりも高いが、オペランドがかっこで囲まれていない。

  • sizeof 演算子のオペランドでかっこが使用されていない。

このルールの違反は、代入演算子、単項演算子、添字演算子、コンマ演算子に対しては報告されません。

トラブルシューティング

ルール違反を想定していてもその違反が表示されない場合、コーディング規約違反が想定どおりに表示されない理由の診断を参照します。

すべて展開する

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 ルールに準拠するには、式の各演算にかっこを加えます。1 つの修正方法を以下に示します。

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

この例では、MISRA ルール 12.1 の違反が前処理コードで示されます。この違反では、演算の正しい順序が分からない場合、結果が予期せぬものとなり、問題を発生させる可能性があります。

修正 — かっこで明確化

この MISRA ルールに準拠するには、式の各演算にかっこを加えます。1 つの修正方法を以下に示します。

# 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 カテゴリ: 推奨

バージョン履歴

すべて展開する


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.