Main Content

AUTOSAR C++14 Rule M5-0-15

Array indexing shall be the only form of pointer arithmetic

Description

Rule Definition

Array indexing shall be the only form of pointer arithmetic.

Rationale

You can traverse an array in two ways:

  • Increment or decrement an array index, and then use the array index to access an element.

  • Increment or decrement a pointer to the array, and then dereference the pointer.

The first method is clearer and less error-prone. All other forms of explicit pointer arithmetic introduce the risk of accessing unintended memory locations.

As an exception, incrementing or decrementing pointer based iterators is compliant with this rule.

Polyspace Implementation

The checker flags:

  • Arithmetic operations on all pointers, for instance p+I, I+p and p-I, where p is a pointer and I an integer..

  • Array indexing on nonarray pointers.

Polyspace® does not flag incrementing or decrementing pointer based iterators, including these standard iterator types:

  • iterator

  • cont_iterator

  • reverse_iterator

  • const_reverse_iterator

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#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]);
	
}

In this example, indexing is done by using array indexing and by calculating the pointer values explicitly. In the function foo():

  • Polyspace flags the instances where a pointer value is explicitly calculated, such as p_int+1 or *(p_int+5).

  • Polyspace flags the use of array indexing on the nonarray pointer p_int.

Polyspace does not flag uses of array indexing on an array that is compliant with this rule.

Incrementing and decrementing iterators to containers is compliant with this rule by exception. Because sumVec() increments an iterator object, Polyspace does not flag the increment operation. This exception does not apply to raw pointers. For instance, sumValues is instantiated in foo() with int*. Polyspace flags incrementing the raw pointer. In modern C++, the best practice is to use range-based for loops, as shown in the function sumVecModern().

Check Information

Group: Expressions
Category: Required, Automated

Version History

Introduced in R2019a