That is correct, but overlooks that UB can be used for good purposes too; gcc's -ftrapv and -fwrapv select (conforming) behavior for that UB and the former can be used to detect signed integer overflow and underflow bugs without false positives. The same is not true for unsigned integer types.> But you still need to reject the positive values that correspond to those negative ones.
> Or an argument for using them, because they don't overflow, and thus have beenshown time and again to benefit from some compiler optimisations. There's areason why proposals to remove this particular UB keep being rejected.
That's incorrect. Signed integers do absolutely overflow (and underflow), by design constraints alone it can't represent as many positive values as an unsigned integer of the same size. What it means is when it does overflow it's UB.i.e. it could do anything, this could mean having the exact same wrap around behavior as unsigned integers, but it could also mean the result could be 0, or some other value entirely, it could even have inconsistent behavior for the exact same input. UB is UB. While it will **likely** not format your hard drive, what it does mean is that there are no guarantees as to the resulting value would be.
Unsigned integers on the other hand always works for indexing, even in overflow conditions, because of modular math. It provides guarantees that are predictable.
Using the result of an overflowed unsigned integer operation as
an index very likely does not do what the programmer intended, but
it is difficult for tools to reliably identify when modular math
was not intended; the lack of UB means there are false positives.
I find the use of UB to employ bug detection tools useful. Looking
forward, contracts will provide a way to identify such bugs
without depending on UB or having to perform range checks on
either the caller of callee side of the index operation.
We do have the option of redefining signed integer overflow and
underflow as erroneous behavior instead of undefined behavior.
That would provide predictable behavior while still allowing -ftrapv to be a conforming option, but
might disallow some optimization techniques.
Tom.
From: Std-Proposals <std-proposals-bounces@lists.isocpp.org> on behalf of Thiago Macieira via Std-Proposals <std-proposals@lists.isocpp.org>
Sent: Wednesday, December 11, 2024 2:28:30 PM
To: std-proposals@lists.isocpp.org <std-proposals@lists.isocpp.org>
Cc: Thiago Macieira <thiago@macieira.org>
Subject: Re: [std-proposals] Signed sizes
On Wednesday 11 December 2024 05:31:07 Brasilia Standard Time Tiago Freire via
Std-Proposals wrote:
> Well, it does only if you reject negative values. Make it unsigned, and you
> don’t need to reject negative values because unsigned values cannot be
> negative. That’s the point.
But you still need to reject the positive values that correspond to those
negative ones. They would by construction always be larger than the
container's size, so a single bounds check is necessary everywhere except in
resizing operations. For the resizing operations, you can also the check and
let the memory allocation fail, but strictly speaking containers should not
rely on it.
As for whether compilers replace a
s >= 0 && s < size
with
u < unsigned(size)
is a QoI issue.
> Case in point Qt is a good example of an API that uses signed indexing, and
> it’s a very large pain point (for me) because it doesn’t match well with
> the things you want to use the containers for, introducing failure modes
> and pain points that simply do not exist with the standard containers
> precisely because unsigned is and should be the right type for indexes.
And the point the OP made is that you must use signed for distances, therefore
you will have different types for different things. Instead of having a single
set of rules for "all the numbers in a container", we have two.
> Signed integers also overflow, except it is UB in the standard, which makes
> it an argument against using signed values, not for.
Or an argument for using them, because they don't overflow, and thus have been
shown time and again to benefit from some compiler optimisations. There's a
reason why proposals to remove this particular UB keep being rejected.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Principal Engineer - Intel DCAI Platform & System Engineering
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals