c++c++23

Is subtracting two pointers to the same type meaningful if those pointers point to items in different arrays?


This is a bit of a silly question, but I think it is interesting.

I was experimenting with pointers and alignment, and wondered if it was possible to subtract two different pointers where those pointers each point to items in different arrays.

Subtracting two pointers is usually expected to produce a value which represents the number of elements between two items in an array.

For example, here is some valid code which works as expected:

unsigned short *p_short = new unsigned short[100];
unsigned short *p_1 = &p_short[10];
unsigned short *p_2 = &p_short[20];

std::cout << p_2 - p_1 << std::endl;
// should produce the value `10`.
// There are 10 `unsigned short`s between the
// two pointers.
// Note: NOT `20`. The subtraction does not
// calulate the number of bytes between the
// two pointers.

However, in the latter case, is the result of the subtraction meaningful?

Possible example with output: This is an example of something which is probably unlikely to produce a meaningful result.

auto p1 = new unsigned short[100];
auto p2 = new unsigned short[100];
std::cout << p2 - p1 << std::endl;

Output: 104.

(However I have seen other values, such as -6148914691236517216.)


Solution

  • The result is not only meaningless, it results in undefined behavior:

    From [expr.add]:

    When two pointer expressions P and Q are subtracted, the type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as std​::​ptrdiff_t in the <cstddef> header ([support.types.layout]).

    • If P and Q both evaluate to null pointer values, the result is 0.
    • Otherwise, if P and Q point to, respectively, array elements i and j of the same array object x, the expression P - Q has the value i−j.
    • Otherwise, the behavior is undefined.