Also an important note: if you use special types like ptrdiff_t and size_t, you must not use the underlying native type printf specifiers when printing them. e.g. never print a ptrdiff_t using %ld, use the ptrdiff_t format specifier %td. (because some systems may say ptrdiff_t is long while others may say long long, and all your printf strings will then print compile time warnings.) Also see https://en.wikipedia.org/wiki/Printf_format_string#Length_fi...
A diff can be negative, whereas a size can't. However, my inclination was to ask the opposite: doesn't ptrdiff_t need to actually be larger than size_t if it must hold signed values and still cover the entire size_t range of inputs?
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.
"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.
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.]
[+] [-] aCthrowa|10 years ago|reply
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.
[+] [-] tomvbussel|10 years ago|reply
[+] [-] ben0x539|10 years ago|reply
[+] [-] 0x0|10 years ago|reply
[+] [-] seiji|10 years ago|reply
This page is a much shorter summary than the article: http://www.gnu.org/software/libc/manual/html_node/Important-...
Also an important note: if you use special types like ptrdiff_t and size_t, you must not use the underlying native type printf specifiers when printing them. e.g. never print a ptrdiff_t using %ld, use the ptrdiff_t format specifier %td. (because some systems may say ptrdiff_t is long while others may say long long, and all your printf strings will then print compile time warnings.) Also see https://en.wikipedia.org/wiki/Printf_format_string#Length_fi...
Plus, the medium article is a complete copy/paste of this 2009 article: http://www.viva64.com/en/a/0050/ — looks like the account https://news.ycombinator.com/user?id=PVS-Studio is copying from viva64 and posting to medium for a lot of old articles.
[+] [-] nhaehnle|10 years ago|reply
size_t is an unsigned type - it is used to represent the sizes of objects in memory, which can never be negative.
[+] [-] hamburglar|10 years ago|reply
[+] [-] AndreyKarpov|10 years ago|reply
1) http://www.viva64.com/en/l/0013/
2) http://www.viva64.com/en/b/0039/
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] colomon|10 years ago|reply
[+] [-] gjm11|10 years ago|reply
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|10 years ago|reply
"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|10 years ago|reply
[EDITED to add: Having said which, the above isn't really any wronger than the OP which is full of mistakes.]