user3156285
user3156285

Reputation: 353

Is it safe to calculate pointer offset using nullptr?

Suppose I have two pointers:

char* p1 = nullptr;
char* p2 = std::malloc( 4 );
std::size_t offset = p2 - p1;

Is it safe to get offset in this way? So far it works fine on my computer. But I'm wondering if the offset can exceed the maximum number of size_t such that this method fails?

Upvotes: 2

Views: 1167

Answers (3)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158569

This is undefined behavior, from the draft C++ standard section 5.7 Additive operators:

When two pointers to elements of the same array object are subtracted, the result is the difference of the subscripts of the two array elements. 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 header (18.2). [...] Unless both pointers point to elements of the same array object, or one past the last element of the array object, the behavior is undefined.82

Also as the reference mentions, the result is std::ptrdiff_t not size_t.

you can on the other hand add or subtract the value 0 which is covered in paragraph 7:

If the value 0 is added to or subtracted from a pointer value, the result compares equal to the original pointer value. If two pointers point to the same object or both point one past the end of the same array or both are null, and the two pointers are subtracted, the result compares equal to the value 0 converted to the type std::ptrdiff_t.

If you want to convert a pointer to an integral value then you should use either intptr_t or uinitptr_t:

intptr_t   integer type capable of holding a pointer
uintptr_t  unsigned integer type capable of holding a pointer

For example:

uintptr_t ip = reinterpret_cast<uintptr_t>( p2 ) ;

Upvotes: 6

Some programmer dude
Some programmer dude

Reputation: 409364

In addition to the answer by Wojtek, pointer arithmetic can and should only be done between related pointers. For example if you have e.g. char* p3 = p2 + 4, then you could do p3 - p2 to get the difference between the two pointers, that would be legal.

However, things like

char* p4 = new char[4];
std::cout << p4 - p2 << '\n';

is not legal, as p2 and p4 are not related.

Upvotes: 3

Wojtek Surowka
Wojtek Surowka

Reputation: 21003

No it is not safe. Basically the only thing you can do with null pointer is to compare it with another pointer. As for addition and subtraction one can only add or subtract zero to a null pointer, and subtract two null pointers - which may be useful in generic programming. Your case is undefined behaviour.

Upvotes: 3

Related Questions