In this blog entry by Andrey Karpov entitled, "About size_t
and ptrdiff_t
" he concludes with
As the reader can see, using ptrdiff_t and size_t types gives some advantages for 64-bit programs. However, it is not an all-out solution for replacement of all unsigned types with size_t ones. Firstly, it does not guarantee correct operation of a program on a 64-bit system. Secondly, it is most likely that due to this replacement, new errors will appear, data format compatibility will be violated, and so on. You should not forget that after this replacement, the memory size needed for the program will greatly increase as well. Increase of the necessary memory size will slow down the application's work, for the cache will store fewer objects being dealt with.
I don't understand these claims, and I don't see them addressed in the article,
"it is most likely that due to this replacement, new errors will appear, data format compatibility will be violated, and so on."
How is that likely, how can there be no error before the migration and the type-migration result in an error? It's not clear when the types (size_t
and ptrdiff_t
) seem to be more more restrictive than what they're replacing.
You should not forget that after this replacement, the memory size needed for the program will greatly increase as well.
I'm unclear of how or why the memory size needed would "greatly" increase, or increase at all? I understand though that if it did Andrey's conclusions follow.
The article contains very dubious claims.
First of all,
size_t
is the type returned bysizeof
.uintptr_t
is an integer type that can store any pointer tovoid
.The article claims that
size_t
anduintptr_t
are synonymous. They're not. On for example segmented MSDOS with large memory models the maximum number of elements in an array would have fit in asize_t
of 16 bits, but a pointer requires 32 bits. They're synonymous on our common Windows, Linux flat memory models now.Even worse is the claim that you can store a pointer in
ptrdiff_t
, or that it would be synonymous withintptr_t
:That's not true at all.
ptrdiff_t
is the type of the value of pointer subtraction, but pointer subtraction is defined only when both pointers point to the same object or just after it, not just anywhere in the memory.On the other hand
ptrdiff_t
could be chosen to be larger thansize_t
- this is because if you have an array of size larger thanMAX_SIZE / 2
elements, subtracting a pointer to the first element from the pointer to the last element or just beyond will have undefined behaviour ifptrdiff_t
is of the same width assize_t
. Inded, the standard does say thatsize_t
can be only 16 bits wide, butptrdiff_t
must be at least 17](http://port70.net/~nsz/c/c11/n1570.html#7.20.3).On Linux
ptrdiff_t
andsize_t
are of same size - and it is possible to allocate an object on 32-bit Linux that is larger thanPTRDIFF_MAX
elements. And as it was pointed out in the comments that standard doesn't requireptrdiff_t
to be even of the same rank assize_t
, though such an implementation would be pure evil.If one is to follow the advice and use
size_t
andptrdiff_t
to store pointers, one certainly cannot go right.As for the claim that
I'd contest that claim - the memory requirement increase would be rather modest compared to the already-present increased consumption from general 64-bit alignment, alignment of the stack and the 64-bit pointers that are inherent in moving to 64-bit environment.
As for the claim that
That certainly is true, but most probably if you're coding such buggy code, you'd accidentally "fix" old errors in the process, like the
signed/unsigned int
example:where the both original and the new code will have undefined behaviour (accessing array elements out of bounds), but the new code would appear to be "correct" on 64-bit platforms too.