Skip to main content
GameDev.net gamedev.net
🔒 Locked

ptrdiff_t unsafe on 32-bit systems?

Started by generaleskimo Aug 7, 2010 at 10:53 PM 2 replies 1.4k views
Original Post
generaleskimo
generaleskimo
When I was reading the article on 64-bit errors, it got me thinking about ptrdiff_t. On a 32-bit system, ptrdiff_t is a 32 bit signed integer, meaning one bit is dedicated to the sign, while all 32 bits in a pointer are used when addressing. Thus, one could create erroneous results by subtracting pointers to memory more than 2GB apart.

int* temp = (int*)1;int* temp2 = (int*)0xFFFFFFF1;ptrdiff_t diff = temp2 - temp;cout << "ptr diff: " << diff << endl;


On a 32-bit system, you get a negative difference. Theoretically, it is possible to get the same issue on a 64-bit system, but you would need over 8EB (that's exabytes) of RAM.

So, why is it safe to use ptrdiff_t for this purpose at all? It seems extremely dangerous to me. All the system has to do is allocate you memory over 2GB apart!
===========================";" is the best key ever; you can use it to end lines when you are too lazy to use ENTER;
taz0010
taz0010
It's only safe to compare pointers into the same allocated block of memory. Allocations bigger than 2GB (7fffffff) fail in 32 bit mode.
frob
frob
Quote:
Original post by generaleskimo
So, why is it safe to use ptrdiff_t for this purpose at all? It seems extremely dangerous to me. All the system has to do is allocate you memory over 2GB apart!

The standard is very clear about that.

When you perform pointer addition or subtraction, it says:
Quote:
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. ... 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.

So your code sample is a bug. It might work, or it might crash, or it might format your hard drive.

Let's assume you can convince your system to give you an extremely large block of memory. You've got to have more than 2GB in a single block, and you subtract one end from the other:
Quote:
As with any other arithmetic overflow, if the result does not fit in the space provided, the behavior is undefined.


So if you happen to have a single block of memory that is larger than 2GB and you take a large pointer difference, you will get general arithmetic overflow's undefined behavior.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.