On 3/12/18, Myria <email@example.com> wrote:
> On Mon, Mar 12, 2018 at 13:32 Lawrence Crowl <Lawrence@crowl.org> wrote:
>> On 3/12/18, Myria <firstname.lastname@example.org> wrote:
>>> The severity of the current situation is that I generally avoid signed
>>> integers if I intend to do any arithmetic on them whatsoever, lest the
>>> compiler decide to make demons come out of my nose.
>>> And even then, I'm not safe:
>>> std::uint16_t x = 0xFFFF;
>>> x *= x; // undefined behavior on most modern platforms
>> How? The C++ standard defines unsigned arithmetic as
>> modular arithmetic.
> But that's the catch: it's double secret signed arithmetic. [...]
> On a "typical modern platform", std::uint16_t is unsigned short. [...]
> 65535 * 65535 overflows a signed int on a typical 32-bit int platform,
> which is undefined behavior.
>> More importantly, what happens to your program when x*x < x?
> The code that led me to finding this was a 16-bit variant of the FNV
> hash function, so it worked properly after the correct casts were added
> to allow the wrap.
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.