Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

MISRA.PTR.ARITH

Pointer is used in arithmetic or array index expression.

MISRA-C Rule 17.1 (required): Pointer arithmetic shall only be applied to pointers that address an array or array element.

[Undefined 30]

Addition and subtraction of integers (including increment and decrement) from pointers that do not point to an array or array element results in undefined behaviour.

MISRA-C Rule 17.4 (required): Array indexing shall be the only allowed form of pointer arithmetic.

Array indexing is the only acceptable form of pointer arithmetic, because it is clearer and hence less error prone than pointer manipulation. This rule bans the explicit calculation of pointer values. Array indexing shall only be applied to objects defined as an array type. Any explicitly calculated pointer value has the potential to access unintended or invalid memory addresses. Pointers may go out of bounds of arrays or structures, or may even point to effectively arbitrary locations. See also Rule 21.1.

Example

void my_fn(uint8_t * p1, uint8_t p2[])
{
   uint8_t index = 0U;
   uint8_t * p3;
   uint8_t * p4;

   *p1 = 0U;
   p1 ++;           /* not compliant - pointer increment               */
   p1 = p1 + 5;     /* not compliant - pointer increment               */
   p1[5] = 0U;      /* not compliant - p1 was not declared as an array */
   p3 = &p1[5];     /* not compliant - p1 was not declared as an array */
   p2[0] = 0U;
   index ++;
   index = index + 5U;
   p2[index] = 0U;  /* compliant                                       */
   p4 = &p2[5];     /* compliant
*/
}
   uint8_t a1[16];
   uint8_t a2[16];
   my_fn(a1, a2);
   my_fn(&a1[4], &a2[4]);
   uint8_t a[10];
   uint8_t * p;
   p = a;
   *(p+5) = 0U;    /* not compliant                                    */
   p[5] = 0U;      /* not compliant                                    */

MISRA-C++ Rule 5-0-15 (required): Array indexing shall be the only form of pointer arithmetic.

Rationale

Array indexing is the only acceptable form of pointer arithmetic, because it is clearer and hence less error prone than pointer manipulation. This rule bans the explicit calculation of pointer values. Array indexing shall only be applied to objects defined as an array type.

Any explicitly calculated pointer value has the potential to access unintended or invalid memory addresses. Pointers may go out of bounds of arrays or structures, or may even point to effectively arbitrary locations.

Exception

The increment/decrement operators may be used on iterators implemented by pointers to an array.

Example

template < typename IterType >
uint8_t sum_values ( IterType iter, IterType end )
{
   uint8_t result = 0;

   while ( iter != end )
   {
      result += *iter;
      ++iter;        // Compliant by exception
   }
   return result;
}

void my_fn ( uint8_t * p1, uint8_t p2[ ] )
{
   uint8_t index = 0;
   uint8_t * p3;
   uint8_t * p4;

   *p1 = 0;
   ++index;
   index = index + 5;

   p1 = p1 + 5;   // Non-compliant — pointer increment
   p1[ 5 ] = 0;   // Non-compliant — p1 was not declared as array
   p3 = &p1[ 5 ]; // Non-compliant — p1 was not declared as array
   p2[ 0 ] = 0;
   p2[ index ] = 0; // Compliant
   p4 = &p2[ 5 ];   // Compliant
}

uint8_t a1[ 16 ];
uint8_t a2[ 16 ];

my_fn ( a1, a2 );
my_fn ( &a1[ 4 ], &a2[ 4 ] );

uint8_t a[ 10 ];
uint8_t * p;

p          = a;
*( p + 5 ) = 0;   // Non-compliant
p[ 5 ]     = 0;   // Compliant
sum_values ( &a1[ 0 ], &a1[ 16 ] );