Main Content

CERT C++: INT36-C

Converting a pointer to integer or integer to pointer

Description

Rule Definition

Converting a pointer to integer or integer to pointer.1

Polyspace Implementation

The rule checker checks for Conversion between pointer and integer.

Examples

expand all

Issue

Conversion between pointer and integer is raised when any of these conditions is true:

  • A pointer type is converted into an integral type with smaller size. When converting a pointer of the types intptr_t or uintprt_t into integral types enum, ptrdiff_t, or pid_t, Polyspace raises a defect if the size of pointers and integer types are different in your environment. In i386 environment, both pointers and integer types have a size of 32 bits. In this environment, Polyspace does not flag conversion from a pointer to an integer of same size. But in x86_64 environment where pointers are 64 bits and unsigned integers are 32 bits, Polyspace® flags conversion from pointers to integers of different sizes.

  • An integral type is converted into a raw pointer type. Polyspace flags conversion from integral types to raw pointers regardless of their sizes. For instance, if an integer originates from a pointer and then later, is cast into a pointer, Polyspace flags the conversion from integer to pointer. In this case, the integer and the pointer are of the same size, but the conversion is still flagged.

Risk

The mapping between pointers and integers is not always consistent with the addressing structure of the environment.

Converting from pointers to integers can create:

  • Truncated or out of range integer values.

  • Invalid integer types.

Converting from integers to pointers can create:

  • Misaligned pointers or misaligned objects.

  • Invalid pointer addresses.

Fix

Where possible, avoid pointer-to-integer or integer-to-pointer conversions. If you want to convert a void pointer to an integer, so that you do not change the value, use types:

  • C99 — intptr_t or uintptr_t

  • C90 — size_t or ssize_t

Example — Integer to Pointer Conversions
unsigned int* badintptrcast(void)
{
    int* ptr;
    unsigned long long int_same_as_ptr ;
    unsigned int int_smaller_than_ptr;

    unsigned int* ptr0 = (unsigned int*)0xdeadbeef; //Noncompliant
    /*int to ptr of same size*/
    ptr = (int*)int_same_as_ptr;  //Noncompliant
    
    /*int to ptr of different size*/
    ptr = (int*)int_smaller_than_ptr;  //Noncompliant

    return (unsigned int*)(ptr0 - (unsigned int*)ptr);  //Noncompliant
}

In this example, Polyspace flags the conversions that might be unsafe. For instance:

  • The conversion of 0xdeadbeef to unsigned int* causes alignment issues for the pointer. Polyspace flags the conversion.

  • The conversion of the int_same_as_ptr and int_smaller_than_ptr to int* pointers might result in invalid pointer address. Polyspace flags these conversion.

  • The return statement casts ptrdiff_t to a pointer. This pointer might not point to an invalid address. Polyspace flags the conversion.

Correction — Use intptr_t

One possible correction is to use intptr_t types to store addresses. When storing the result of subtracting two pointers, use the type ptrdiff_t.

#include<cstdint>
#include<stddef.h>
ptrdiff_t badintptrcast(void)
{
    intptr_t ptr;
    unsigned long long int_same_as_ptr ;
    unsigned int int_smaller_than_ptr;

    intptr_t ptr0 = (intptr_t)0xdeadbeef; //Compliant
    /*int to ptr of same size*/
    ptr = (intptr_t)int_same_as_ptr;  //Compliant
    
    /*int to ptr of different size*/
    ptr = (intptr_t)int_smaller_than_ptr;  //Compliant

    int offset = 0;
    return (ptrdiff_t)(ptr0 - offset);//Compliant
    
}

Check Information

Group: 03. Integers (INT)

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.