
About size_t and ptrdiff_t - PVS-Studio
https://medium.com/@CPP_Coder/about-size-t-and-ptrdiff-t-a1654234d842
======
aCthrowa
This may be practically correct, but is semantically very very wrong.

size_t represents the size of objects in memory. So of course it scales with
virtual memory space.

ssize_t is like size_t (same width), but signed. It's useful for routines that
want to return a size_t or error (network routines like send/recv).

ptrdiff_t is specifically for the result of subtracting one pointer from
another. Obviously it scales with pointer size as well.

~~~
ben0x539
ssize_t isn't standard C so it doesn't get you very far for portability.

~~~
throwaCagain
POSIX gets you pretty far.

------
0x0
Why do you need a "ptrdiff_t" type, why isn't "size_t" sufficient?

~~~
colomon
Also, why use the signed ptrdiff_t for a loop index that is never negative?

~~~
pmelendez
"size_t can store a pointer, it is better to use another unsinged integer type
uintptr_t for that purpose " So he is actually recommending the unsigned
version. Although there are some people (like the Google guidelines for C++)
that recommend not using unsigned types because of overflows (which is
arguable but it is a point)

------
gjm11
Let me enumerate the worst errors in this article.

1\. Their "headline" recommendation near the start is that you should write
things like for (ptrdiff_t i=0; i<...; ++i) { ... a[i]; ... }. No, for this
purpose you should almost certainly be using size_t rather than ptrdiff_t. The
article nowhere gives any reason for preferring ptrdiff_t to size_t in this
context. (There might be some; e.g., if you're processing that array in
reverse order, you might want to test whether i>=0, and that won't give useful
results if i is of an unsigned type. But you won't learn that from the
article.)

2\. The article claims that size_t and uintptr_t are synonyms, and likewise
for ptrdiff_t and intptr_t. I dare say in practice they're always equivalent
types, but they certainly don't _mean_ the same thing and encouraging readers
to think they do is a bad idea.

3\. Similarly, the article says that a size_t or ptrdiff_t "can store a
pointer". There are -- as the article admits -- integral types actually
guaranteed to be usable in this way, namely intptr_t and uintptr_t. There is
no guarantee that you can do that with size_t or ptrdiff_t, and no good reason
why you should try.

4\. The article says that ptrdiff_t "could store the maximum size of a
theoretically possible array of any type". No, that would be size_t.

5\. The article lists things that size_t and ptrdiff_t are "usually used for".
The difference between the two lists is that the one for ptrdiff_t includes
"size storage", which is exactly backwards. (You'd think the name size_t might
be a clue.)

6\. Those lists include, in both cases, "storing pointers". No: use pointer
types for storing pointers, and if you really truly need to force them into
integral types then use intptr_t or uintptr_t.

7\. In the second example of a "sleeping error" \-- the one with variables A
and B -- the more fundamental problem isn't the failure to use
size_t/ptrdiff_t, it's the fact that the expression A+B is of an unsigned type
but is being used to hold a negative array offset. It's true that using size_t
instead of unsigned will probably make the error go away, but the _right_ way
to make it go away is never to have the equivalent of ((unsigned)-2) in your
code to begin with. You want a signed type for that, and int will do just as
well as ptrdiff_t.

8\. The final section of the article makes it clear that its real goal is to
convince developers that (1) we should use size_t and ptrdiff_t if we care at
all about portability and future-proofing, but (2) converting code to do so is
too painful for human beings, so (3) you should buy their product.

It's maybe a bit unfair to classify that as an "error", but I don't think I
would want to entrust static analysis of integer-type issues to software
written by someone who could write this article.

------
pmalynin
Nitpicks:

"ptrdiff_t type...ptrdiff_t will take 32 bits, on a 64-bit one 64 bits" \--
that's not really true as that would made it equivalent to size_t. So in
reality its 31 bits and 63 bits.

~~~
gjm11
Nope. It's 32 and 64, but it's a signed type (which is why it isn't equivalent
to size_t). The range of possible values is still of size 2^32 or 2^64, it's
just centred at 0.

[EDITED to add: Having said which, the above isn't really any wronger than the
OP which is full of mistakes.]

~~~
pmalynin
What I meant to say is that the text for size_t and ptrdiff_t are identical,
implying that the underlying types are identical. That is there is logical
fallacy.

They author states "The type’s size is chosen so that it could store the
maximum size of a theoretically possible array of any type" and the same is
said for ptrdiff_t, which is quit confusing.

Now I realise that in reality they both use 64 bits, it is somewhat strange to
use the same text for both.

~~~
gjm11
Yeah, the article is just terrible, and when it says a ptrdiff_t can store the
size of any object it's completely wrong.

