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.2012

Pointer is used in arithmetic expression.

MISRA C 2012 Rule 18.4: The +, -, += and -= operators should not be applied to an expression of pointer type

Category: Advisory

Analysis: Decidable, Single Translation Unit

Applies to: C90, C99

Rationale

Array indexing using the array subscript syntax , ptr[expr], is the preferred form of pointer arithmetic because it is often clearer and hence less error prone than pointer manipulation. Any explicitly calculated pointer value has the potential to access unintended or invalid memory addresses. Such behaviour is also possible with array indexing, but the subscript syntax may ease the task of manual review.

Pointer arithmetic in C can be confusing to the novice. The expression ptr+1 may be mistakenly interpreted as the addition of 1 to the address held in ptr. In fact the new memory address depends on the size in bytes of the pointer’s target. This misunderstanding can lead to unexpected behaviour if sizeof is applied incorrectly.

When used with caution however, pointer manipulation using ++ can in some cases be considered more natural; e.g. sequentially accessing locations during a memory test where it is more convenient to treat the memory space as a contiguous set of locations and the address bounds can be determined at compilation time.

Exception

Subject to Rule 18.2, pointer subtraction between two pointers is allowed.

Example

void fn1 ( void ) 
{
  uint8_t a[ 10 ]; 
  uint8_t *ptr; 
  ui nt8_t index = 0U;

  index = index + 1U;      /* Compliant - rule only applies to pointers */
  
  a[ index ] = 0U;         /* Compliant                                 */ 
  ptr = &a[ 5 ];           /* Compliant                                 */

  ptr = a; 
  ptr++;                   /* Compliant - increment operator not +      */ 
  *( ptr + 5 ) = 0U;       /* Non-compliant                             */ 
  ptr[ 5 ] = 0U;           /* Compliant                                 */ 
}

void fn2 ( void ) 
{  
  uint8_t array_2_2[ 2 ][ 2 ] = { { 1U, 2U }, { 4U, 5U } }; 
  uint8_t i = 0U; 
  uint8_t j = 0U; 
  uint8_t sum = 0U;

  for ( i = 0U; i < 2U; i++ ) 
  {
    uint8_t *row = array_2_2[ i ];

    for ( j = 0U; j < 2U; j++ ) 
    {
      sum += row[ j ]; /* Compliant */ 
    } 
  } 
}

In the following example, Rule 18.1 may also be violated if p1 does not point to an array with at least six elements and p2 does not point to an array with at least 4 elements.

void fn3 ( uint8_t *p1, uint8_t p2[ ] )
{
  p1++;                 /* Compliant */ 
  p1 = p1 + 5;          /* Non-compliant */ 
  p1[ 5 ] = 0U;         /* Compliant */
  
  p2++;                 /* Compliant */ 
  p2 = p2 + 3;          /* Non-compliant */ 
  p2[ 3 ] = 0U;         /* Compliant */ 
}

uint8_t a1[ 16 ]; 
uint8_t a2[ 16 ]; 
uint8_t data = 0U;

void fn4 ( void ) 
{
  fn3 ( a1, a2 ); 
  fn3 ( &data, &a2[ 4 ] );
}

See also

Rule 18.1, Rule 18.2