[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: preferring ptrdiff_t to size_t for object counts
From: |
Bruno Haible |
Subject: |
Re: preferring ptrdiff_t to size_t for object counts |
Date: |
Mon, 05 Jun 2017 11:57:34 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-78-generic; KDE/5.18.0; x86_64; ; ) |
Hi Paul,
> GNU Emacs has long been using signed types (typically ptrdiff_t) to count
> objects. This has the advantage that signed integer overflow can be detected
> automatically on some platforms (unfortunately, size_t arithmetic silently
> wraps
> around).
I have one objection, but a big one: The direct use of ptrdiff_t.
Reasons:
1) Like you, I spend time reviewing code other people have written. In these
code reviews, it is important to know whether a variable is known to always
be >= 0 or not.
For example, when we have
int n = ...;
for (int i = 0; i < n; i++) ...
I always have to spend brain cycles around the question "what if n < 0?
Does the code still achieve its goal in this case?"
Whereas if the type clearly states the intent to store only values >= 0,
there is no issue; no extra brain cycles required.
2) Standards change, and the considerations behind 'walloc' may also change.
Do you want, 5 or 10 years from now, to go through hundreds of uses of
'ptrdiff_t' and separate those uses with values >= 0 from those with values
that can be negative? I certainly don't want to.
3) GCC has range types for Ada. I would hope that someday it also has range
types for C or C++. Then, it would be very useful to express the fact that
the values are in the range [0..PTRDIFF_MAX], so that GCC can use it for
optimization.
4) For static analysis tools (gnulib now uses coverity in particular), I can
imagine that an unsigned type is easier to work with than a signed type
(i.e. that the tool can make more inferences and therefore detect more bugs
when using unsigned types).
To this effect, it is useful to use an unsigned type for those counters /
size_t object, *just* for the static analysis tool.
To fix all of these issues, I suggest to use a typedef'ed type, instead. For
example:
typedef ptrdiff_t wsize_t;
And then use wsize_t everywhere.
This solves problems 1), 2), 3), and 4 (through a #ifdefed definition of
wsize_t).
Yes it means that people reading the code will have to memorize one more type
identifier. But it is to their benefit: they will know the values are >= 0
(see point 1).
Bruno