Skip to end of metadata
Go to start of metadata

When two pointers are subtracted, both must point to elements of the same array object or just one past the last element of the array object (C Standard, 6.5.6 [ISO/IEC 9899:2011]); the result is the difference of the subscripts of the two array elements. Otherwise, the operation is undefined behavior. (See undefined behavior 48.)

Comparing pointers using the equality operators == and != has well-defined semantics regardless of whether or not either of the pointers is null, points into the same object, or points one past the last element of an array object or function.

Noncompliant Code Example

In this noncompliant code example, pointer subtraction is used to determine how many free elements are left in the nums array:

#include <stddef.h>
 
enum { SIZE = 32 };
 
void func(void) {
  int nums[SIZE];
  int end;
  int *next_num_ptr = nums;
  size_t free_elements;

  /* Increment next_num_ptr as array fills */

  free_elements = &end - next_num_ptr;
}

This program incorrectly assumes that the nums array is adjacent to the end variable in memory. A compiler is permitted to insert padding bits between these two variables or even reorder them in memory.

Compliant Solution

In this compliant solution, the number of free elements is computed by subtracting next_num_ptr from the address of the pointer past the nums array. While this pointer may not be dereferenced, it may be used in pointer arithmetic.

#include <stddef.h>
enum { SIZE = 32 };
 
void func(void) {
  int nums[SIZE];
  int *next_num_ptr = nums;
  size_t free_elements;

  /* Increment next_num_ptr as array fills */

  free_elements = &(nums[SIZE]) - next_num_ptr;
}

Exceptions

ARR36-C-EX1: Comparing two pointers to distinct members of the same struct object is allowed. Pointers to structure members declared later in the structure compare greater-than pointers to members declared earlier in the structure.

Risk Assessment

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ARR36-C

Medium

Probable

Medium

P8

L2

Automated Detection

Tool

Version

Checker

Description

Astrée17.04ipointer-subtractionPartially checked
Coverity2017.07

MISRA C 2004 17.2

MISRA C 2004 17.3

MISRA C 2012 18.2

MISRA C 2012 18.3

Implemented
LDRA tool suite9.7.1

437 S, 438 S

Fully implemented

Parasoft C/C++test9.5MISRA2008-5_0_17Fully implemented
PRQA QA-C9.3

0487, 0513, 2771, 2772,
2773, 2761,
2762,
2763, 2766, 2767,
2768

Fully implemented

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

SEI CERT C++ Coding StandardCTR54-CPP. Do not subtract iterators that do not refer to the same container
ISO/IEC TS 17961

Subtracting or comparing two pointers that do not refer to the same array [ptrobj]

MITRE CWECWE-469, Use of Pointer Subtraction to Determine Size

Bibliography

 


1 Comment

  1. Larry Jones says, via email:
    > > So from what we can tell, it's OK to compare pointers to members within
    > > the same struct, but not OK to subtract pointers in the same situation.
    > > True or false?

    True (unless they happen to be pointers to char, since the content of
    the struct can be treated as an array of char). Consider a struct with
    an int member, a char member, and another int member, with no padding.
    If you subtract pointers to the two ints, the correct result would be
    something like 1.25, which is nonsensical.