CertC-ARR36

Do not subtract or compare two pointers that do not refer to the same array

Required inputs: IR, StaticSemanticAnalysis

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
Related Guidelines
Taxonomy Taxonomy item Relationship
CERT C CTR54-CPP. Do not subtract iterators that do not refer to the same container Prior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TS 17961 Subtracting or comparing two pointers that do not refer to the same array [ptrobj] Prior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11 CWE-469, Use of Pointer Subtraction to Determine Size 2017-07-10: CERT: Exact
CWE 3.11 CWE-469, Use of Pointer Subtraction to Determine Size 2018-10-18:CERT:CWE subset of rule
Bibliography
[ Banahan 2003] Section 5.3, "Pointers"
Section 5.7, "Expressions Involving Pointers"
[ ISO/IEC 9899:2011] 6.5.6, "Additive Operators"
Excerpt from SEI CERT C Coding Standard: Rules for Developing Safe, Reliable, and Secure Systems (2016 Edition) and SEI CERT C Coding Standard [https://cmu-sei.github.io/secure-coding-standards/sei-cert-c-coding-standard/rules/arrays-arr/arr36-c], Copyright (C) 1995-2026 Carnegie Mellon University. See section 9.4. "3rd-Party Licenses" in the documentation for full details.

Possible Messages

Key

Text

Severity

Disabled

possible_unrelated_ptr_comparison

Comparing possibly unrelated pointers

None

False

possible_unrelated_ptr_subtraction

Subtracting possibly unrelated pointers

None

False

unrelated_ptr_comparison

Comparing unrelated pointers

None

False

unrelated_ptr_subtraction

Subtracting unrelated pointers

None

False

Options

check_non_array_pointers

check_non_array_pointers : bool = False

Whether the check should also consider pointers to non-arrays (e.g., comparison of pointers to different fields). If enabled, a pointer to an object that is not an array is treated as if it were a pointer to the first element of an array with a single element.
 

report_empty_points_to_sets

report_empty_points_to_sets : bool = False

Report cases where one of the pointers involved in the comparison does not point to any value. This can occur e.g. if parameters of entry functions are analyzed, for which no values are known.