C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Signed sizes

From: Tom Honermann <tom_at_[hidden]>
Date: Wed, 11 Dec 2024 11:42:04 -0500
On 12/11/24 11:00 AM, Tiago Freire via Std-Proposals wrote:
> > But you still need to reject the positive values that correspond to
> those negative ones.
>
> Yes, the difference is those "large positive values that correspond to
> the negative ones" are now squarely in the positive domain and you
> only need to write 1 comparison to validate instead of two. And I'm
> sure developers are much more likely drop that extra >=0.
> While the arithmetics work the same regardless of signdness,
> comparisons do not.
>
> (**and surely there are no systems that have more memory available
> than what the max signed integer can represent, so that shouldn't be a
> problem...... right?** đź‘€)
>
> > 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.
>
> 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.
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.
>
> 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_at_[hidden]> on
> behalf of Thiago Macieira via Std-Proposals
> <std-proposals_at_[hidden]>
> *Sent:* Wednesday, December 11, 2024 2:28:30 PM
> *To:* std-proposals_at_[hidden] <std-proposals_at_[hidden]>
> *Cc:* Thiago Macieira <thiago_at_[hidden]>
> *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_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>

Received on 2024-12-11 16:42:09