Hacker News new | ask | show | jobs
by tialaramex 609 days ago
For signed overflow it's fascinating, Herb Sutter (WG21 convenor, Microsoft employee) writes that checking would "incur unacceptable costs".

Now, C++ programmers, were you consulted about these costs? Herb insists they're "unacceptable" but he provides no further information as to what the cost actually was, or who decided whether that cost was acceptable, much less how this could generalize across a wide variety of domains and platforms.

What's Herb's answer? You might hope that Herb would say OK, we'll provide wrapping for these types by default, it's not checked arithmetic but at least it's not UB. Nope.

3 comments

C & C++ lack a particular sort of behavior that could solve a bunch of problems.

They've got undefined behavior: The standard imposes no requirements. Anything can happen. Assume the worst.

They've got unspecified behavior: Only covers behavior caused by an unspecified value or where the standard provides multiple choices, where the implementation need not document which choices are made in which situations.

They've got implementation-defined behavior: Unspecified behavior that the implementation must document.

They don't have a category for "Undefined behavior but the implementation must document". A lot of what is currently undefined behavior could better be put into this category, if it existed.

C++ 26 will (almost certainly, it's in the draft) add Erroneous Behaviour.

EB is well defined but definitely wrong, so it's a way for the standard to say:

Do not allow this to happen, but if you do, the consequence is definitely that.

The specific EB in the C++ 26 draft is the value of default uninitialized primitives. So e.g. int k; std::cout << k << "\n";

In C++ 23 and previous versions that's Undefined Behaviour, maybe it prints the lyrics to the National Anthem of the country where the compiler ran? Maybe it deletes all your files. But in C++ 26 the Erroneous Behaviour is that there's some integer value k, which your compiler vendor knew (and might tell you or even let you change it) and it prints that value, but you're naughty because this is definitively an error when it happens.

With GCC/clang can just add checking with -fsanitize=signed-integer-overflow -fsanitize-undefined-trap-on-error.

For my main software project, which is some numerical software for magnetic resonance imaging, this adds 12212 checks and the optimizer reduces them down to 3803. But I haven't done benchmarking yet, but I would guess that for most software it would not matter.

Basically the behavior is hardware-dependent, and nobody wants to mandate that C++ compilers generate a ton of extra instructions on hardware which does not behave a particular way.

Of course you can define your own checked integer types, using inline assembly to check the overflow flag where available.

Just so we're clear, yes, it's "hardware-dependent", but literally every single architecture and CPU model does the same reasonable thing, which is to wrap into the negative.

Any architecture that doesn't use 2s complement is so esoteric by now that it does not make any sense for a general-purpose C compiler to pretend they exist.