I'm quite new at working with C++ and haven't grasped all the intricacies and subtleties of the language.
What is the most portable, correct and safe way to add an arbitrary byte offset to a pointer of any type in C++11?
SomeType* ptr;
int offset = 12345 /* bytes */;
ptr = ptr + offset; // <--
I found many answers on Stack Overflow and Google, but they all propose different things. Some variants I have encountered:
ptr = (SomeType*)(((char*)ptr) + offset);
Cast to unsigned int
:
ptr = (SomeType*)((unsigned int)ptr) + offset);
ptr = (SomeType*)((size_t)ptr) + offset);
"The size of size_t
and ptrdiff_t
always coincide with the pointer's size. Because of this, it is these types that should be used as indexes for large arrays, for storage of pointers and pointer arithmetic." - About size_t and ptrdiff_t on CodeProject
ptr = (SomeType*)((size_t)ptr + (ptrdiff_t)offset);
Or like the previous, but with intptr_t
instead of size_t
, which is signed instead of unsigned:
ptr = (SomeType*)((intptr_t)ptr + (ptrdiff_t)offset);
Only cast to intptr_t
, since offset
is already a signed integer and intptr_t
is not size_t
:
ptr = (SomeType*)((intptr_t)ptr) + offset);
And in all these cases, is it safe to use old C-style casts, or is it safer or more portable to use static_cast
or reinterpret_cast
for this?
Should I assume the pointer value itself is unsigned or signed?
I would use something like:
unsigned char* bytePtr = reinterpret_cast<unsigned char*>(ptr);
bytePtr += offset;