Subject: Re: [ub] A proposal to define signed overflow submitted?
From: Lawrence Crowl (Lawrence_at_[hidden])
Date: 2018-03-12 19:22:12
On 3/12/18, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> wrote:
> On Mar 12, 2018, Lawrence Crowl <Lawrence_at_[hidden]> wrote:
>> So the application intended modular arithmetic? I was concerned about
>> the normal case where 'unsigned' is used to constrain the value range,
>> not to get modular arithmetic.
> IMNSHO, if anyone is using unsigned types "to constrain the value range,"
> they are doing computers wrong. That is *not* what signed vs. unsigned
> types are for.
I note that size_t is unsigned to constrain the value range, not to obtain
> As Lawrence himself wrote earlier in this thread:
>> If integer overflow is undefined behavior, then it is wrong. Tools can
>> detect wrong programs and report them.
> The contrapositive is: "If the programmer is using a type where integer
> overflow is well-defined to wrap, then we can assume that the program
> relies on that wrapping behavior (because there would otherwise be a
> strong incentive for the programmer to use a type that detects and
> reports unintended overflow)."
Yes. For the most part, programmers should be explicit when they want
anything other than mathematical integers.
> The original design for the STL contained the "unsigned for value range"
> antipattern. Consequently, they ran into trouble immediately: for
> example, `std::string::find
> <https://en.cppreference.com/w/cpp/string/basic_string/find>` returns an
> index into the string, naturally of type `std::string::size_type`. But
> size_type is unsigned! So instead of returning "negative 1" to indicate
> the "not found" case, they had to make it return `size_type(-1)`, a.k.a.
> `std::string::npos` -- which is a positive value! This means that
> callers have to write cumbersome things such as
> if (s.find('k') != std::string::npos)
> where it would be more natural to write
> if (s.find('k') >= 0)
I won't disagree with the easier syntax of the latter, but I note that
the function itself is returning two things: the search status, and iff
successful the index of the found object.
> This is sort of parallel to my quotation of Lawrence above: If every
> possible value in the domain of a given type is a valid output (e.g.
> from `find`), then there is no value left over with which the function
> can signal failure at runtime. And if every possible value in the
> domain is a valid *input* (e.g. to `malloc`), then there is no way for
> the function to detect incorrect input at runtime.
This problem is why I proposed the status_value class.
> If it weren't for the STL's `size_type` snafu continually muddying the
> waters for new learners, I doubt people would be falling into the
> "unsigned for value range" antipattern anymore.
Well, I would, but I tend to use it to avoid ill-formed negative inputs.
-- Lawrence Crowl
SG12 list run by herb.sutter at gmail.com