More on undefined behavior. This time I take on CERT.
2 plus ones
Shared publicly•View activity
- Good points, Jon. The GCC team once inserted a warning for exactly such undefined behaviour, due to a bug report and a disgruntled user. So now you get GCC warning you every time it optimises:
assuming signed overflow does not occur when assuming that (X + c) < X is always falseMar 4, 2014
- Thiago, thanks for pointing this out.
My guesses: This is almost never helpful to users and this warning is almost always turned off. (And when it isn't turned off, it is because the users hasn't set treat-warnings-as-errors, which itself is not likely to end well.)Mar 4, 2014
- It's enabled by -O2. So it's pretty noisy and I've seen many people trying to hide the warning by changing the code, when there's nothing wrong with the code in the first place.Mar 4, 2014
- Personally, I think the real problem is with the definition of integer types in C and C++. They are a leaky abstraction. The real issue here is that it is too easy to accidentally invoke undefined behavior, and no way to tell the compiler when there is definitely no possibility of overflow.
In general, what we really want is just an integer, and we do not want to care too much about the bounds. However, all integer types built in to the language are bounded with behavior on overflow that isn't always what the user intends. The 'ideal' integer type would be able to represent any integer.
Obviously this isn't what people would use and I would not even recommend that this be what people use due to performance concerns.
Rather than making all integers boundless or using integers that have for the most part implicit bounds, it seems to me that a more fruitful approach would be to make all bounds explicit. If you need a number between 1 and 100, say it, don't say `int` or `unsigned` or `uint8_t`. The result type of multiplying two such numbers is not that same type, it's a number between 1 and 10000, and the compiler should be able to allocate appropriate storage automatically, not try to shoe-horn it into the type of the arguments.
At least, that was the philosophy behind https://bitbucket.org/davidstone/bounded_integer (which I don't recommend people use at this point if they care about interface stability).
Unfortunately, `bounded_integer::native_integer<1, 100>` just doesn't have quite the same ring to it as `int`. If only I could have `int<1, 100>`...Mar 24, 2014
- I ran into this exact same situation at work. It took us a few minutes to reason about how to rewrite the code to check for UB first.Apr 4, 2015