Main Content

CERT C: Rule ARR37-C

Do not add or subtract an integer to a pointer to a non-array object

Description

Rule Definition

Do not add or subtract an integer to a pointer to a non-array object.1

Polyspace Implementation

The rule checker checks for

  • Invalid assumptions about memory organization

  • Pointer arithmetic on class, structure, or union fields

Examples

expand all

Issue

Invalid assumptions about memory organization occurs when you compute the address of a variable in the stack by adding or subtracting from the address of another non-array variable.

Risk

When you compute the address of a variable in the stack by adding or subtracting from the address of another variable, you assume a certain memory organization. If your assumption is incorrect, accessing the computed address can be invalid.

Fix

Do not perform an access that relies on assumptions about memory organization.

If you want to justify this violation, add comments to your result or code to avoid another review. See:

Example - Reliance on Memory Organization
void func(void) {
    int var1 = 0x00000011, var2;
    *(&var1 + 1) = 0; //Noncompliant
}

In this example, the programmer relies on the assumption that &var1 + 1 provides the address of var2. Therefore, an Invalid assumptions about memory organization appears on the + operation. In addition, a Pointer access out of bounds error also appears on the dereference.

Correction — Do Not Rely on Memory Organization

One possible correction is not perform direct computation on addresses to access separately declared variables.

Issue

The issue Pointer arithmetic on class, structure, or union fields occurs when you attempt to access a field of a class, structure, or union by adding or subtracting from the address of another field. Exceptions include cases where the field is an array and you perform pointer arithmetic on the array.

Risk

When you perform pointer arithmetic on the pointer to a field of a class, structure, or union, you make the assumption that the other fields come in a contiguous order in memory. This assumption is not always true and can lead to unexpected results or undefined behavior.

Fix

Do not perform pointer arithmetic on class, structure, or union fields. Redefine class, structure, or union to use an array instead of separate fields if pointer arithmetic is necessary.

Example — Pointer Arithmetic on Structure Field
#include <stdio.h>

struct my_struct {
  int x;
  int y;
};

void print_struct(const struct my_struct* s) {
  const int* p;
  for (p = &(s->x); p <= &(s->y); p++) {     //Noncompliant
    printf("%d\n", *p);
  }
}

int main() {
  struct my_struct s = { 1, 2 };
  print_struct(&s);
  return 0;
}

In this example, the function print_struct() takes a pointer to the structure my_struct. print_struct() attempts to print the values of the fields of my_struct using a for-loop.

The for-loop initializes the pointer const int* p to point to the x field of my_struct and increments p until p points to the y field. Because x and y are not elements of an array and you use pointer arithmetic on them, Polyspace reports a rule violation.

Correction — Redefine Structure to Contain Array

Redefine the structure my_struct to contain an array of two integer values and use a pointer to the array instead.

#include <stdio.h>

struct my_struct {
  int nums[2];
};

void print_struct(const struct my_struct* s) {
  const int* p;
  for (p = s->nums; p <= s->nums + 1; p++) {     //Compliant
    printf("%d\n", *p);
  }
}

int main() {
  struct my_struct s = { { 1, 2 } };
  print_struct(&s);
  return 0;
}

Check Information

Group: Rule 06. Arrays (ARR)

Version History

Introduced in R2019a

expand all


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.