メインコンテンツ

MISRA C:2012 Rule 13.2

The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders and shall be independent from thread interleaving

説明

ルール定義

The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders and shall be independent from thread interleaving 1 .

根拠

評価の順序に応じて式の結果が異なる値になる場合、その値は処理系定義になります。

スレッド インターリーブの順序に応じて式の結果が異なる値になる場合、C 標準ではスレッド インターリーブの順序を指定していないため、その値は予測不可能になります。このような予測できない動作は、コードに、未定義の動作であるデータ レース状態が含まれる可能性があることを示唆します。

Polyspace 実装

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

  • 同じ変数が式内で複数回変更される、あるいは同じ変数に対して読み取りと書き込みの両方が実行される。

  • 式が複数の評価順序を許可している。

  • 式内で単一の volatile オブジェクトが複数回出現する。

  • 式に複数の volatile オブジェクトが含まれる。

volatile オブジェクトは随時、その値を変更可能であるため、複数の volatile 変数または同じ volatile 変数の複数のインスタンスが含まれる式は、評価順序によって結果が異なる可能性があります。

トラブルシューティング

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

すべて展開する

int a[10], b[10];
#define COPY_ELEMENT(index) (a[(index)]=b[(index)])

void main () {
	int i=0, k=0;

	COPY_ELEMENT (k);         /* Compliant */
	COPY_ELEMENT (i++); /* Noncompliant  */
}

この例では、ステートメント COPY_ELEMENT(i++) において、i++ が 2 回発生し、2 つの式の評価順序が指定されていないためルールに違反します。

void f (unsigned int param1, unsigned int param2) {}

void main () {
    unsigned int i=0;
    f ( i++, i );                 /* Non-compliant */
}

この例では、演算 i++ が 2 番目の引数を f に引き渡す前または後に実行されるのか指定されていないため、ルールに違反します。呼び出し f(i++,i)f(0,0) または f(0,1) に変換できます。

struct {
	volatile float x; 
	volatile float y; 
} volData;

float xCopy;
float yCopy;
float res, res2;

void function4(void) {
	res = volData.x + volData.y;         //Noncompliant
	res = volData.x * volData.x;	  //Noncompliant
	xCopy = volData.x;
	yCopy = volData.y;
	res = xCopy + yCopy;  //Compliant
}  

この例では、式 volData.x + volData.y は複数の volatile オブジェクトを含んでいるため、ルールに準拠していません。この式は、volData.x の値へのアクセス、volData.y の値へのアクセス、および加算の 3 つの演算で構成されています。構造体 volData に含まれる volatile フィールド xy の値は随時、変更される可能性があります。res の値は、どちらの変数が先に読み取られるかによって異なる可能性があります。C 標準では変数の読み取り順序を指定していないため、res の値は、使用されているハードウェアとソフトウェアに依存することになります。Polyspace® は、この式に含まれる volatile オブジェクトのいずれか 1 つにフラグを設定します。同様に、Polyspace は、式 volData.x * volData.x に含まれる volatile オブジェクトのいずれか 1 つにフラグを設定します。

違反を回避するには、volatile 変数を volatile でない一時変数に割り当てて、それらの一時変数を式で使用します。

チェック情報

グループ: 二次的影響
カテゴリ: 必要
AGC カテゴリ: 必要

バージョン履歴

R2014b で導入

すべて展開する


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.