メインコンテンツ

AUTOSAR C++14 Rule M5-0-15

Array indexing shall be the only form of pointer arithmetic.

説明

ルール定義

Array indexing shall be the only form of pointer arithmetic.

根拠

配列を走査するには、次の 2 つの方法があります。

  • 配列インデックスをインクリメントまたはデクリメントしてから、その配列インデックスを使用して要素にアクセスします。

  • 配列を指すポインターをインクリメントまたはデクリメントしてから、そのポインターをデリファレンスします。

最初の方法のほうがわかりやすく、エラーが発生しづらくなります。他の形式の明示的ポインター演算は、いずれも意図しないメモリ位置にアクセスするリスクをもたらします。

例外として、インクリメントまたはデクリメントするポインターに基づく反復子はこのルールに準拠しています。

Polyspace 実装

チェッカーは以下にフラグを設定します。

  • すべてのポインターに対する算術演算、たとえば、p+II+p、および p-I。ここで、p はポインターで、I は整数です。

  • 非配列ポインターの配列インデックス付け。

Polyspace® は、以下の標準の反復子タイプを含め、インクリメントまたはデクリメントするポインターに基づく反復子にフラグを設定しません。

  • iterator

  • cont_iterator

  • reverse_iterator

  • const_reverse_iterator

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

#include<vector>
template < typename IterType >
int sumValues(IterType iter, IterType end)
{
	int result = 0;
	while (iter != end) {
		result += *iter; 
		++iter;  //Noncompliant
	}
	return result;
}
int sumVec(std::vector<int>& v)
{
	int res = 0;
	for (auto it = v.begin(); it != v.end(); ++it) //Compliant by exception
	res += *it;
	return res;
}
int sumVecModern(std::vector<int>& v)
{
	int res = 0;
	for(auto i:v){
		res+=i;	
	}
	return res;
}
void foo(int* p_int, int arr_int[])
{
	p_int = p_int + 1; //Noncompliant
	arr_int[0] = arr_int[1];

	p_int[5] = 0; //Noncompliant
	*(p_int + 5) = 0; //Noncompliant
	arr_int[5] = 0.0;
	
	int a[100];
	std::vector<int> v(100);
	sumValues(&a[0],&a[99]);
	
}

この例では、配列インデックス付けを使用するとともに、ポインター値を明示的に計算することによって、インデックス付けが行われています。関数 foo() では、次の結果になります。

  • Polyspace は、ポインター値が明示的に計算される p_int+1*(p_int+5) などのインスタンスにフラグを設定します。

  • Polyspace は、非配列ポインター p_int での配列インデックス付けの使用にフラグを設定します。

Polyspace は、このルールに準拠している配列での配列インデックス付けの使用にはフラグを設定しません。

コンテナーに対する反復子のインクリメントおよびデクリメントは、例外としてこのルールに準拠しています。sumVec()iterator オブジェクトをインクリメントするため、Polyspace はこのインクリメント操作にフラグを設定しません。この例外は、生のポインターには適用されません。たとえば、sumValuesfoo() 内で int* を使用してインスタンス化されます。Polyspace は、この生のポインターのインクリメントにフラグを設定します。最新の C++ でのベスト プラクティスは、関数 sumVecModern() に示されているように、範囲に基づく for ループを使用することです。

チェック情報

グループ:
カテゴリ: Required、Automated

バージョン履歴

R2019a で導入