On Tue, Nov 27, 2018 at 7:18 PM Steven Watanabe via Boost
On 11/26/2018 03:57 PM, Gavin Lambert via Boost wrote:
Avoiding possible undefined behaviour sounds like a good reason to avoid signed integers in general. (Except where actually required.)
I strongly disagree. Given that some operation has no sensible behavior (for example a + b where the mathematical sum does not fit in the given type), there are four possible ways to solve the problem:
a) Define the behavior to do something b) Assume that it never happens c) Check for it and issue an error d) Make it syntactically impossible
(b) may give better performance, but would be unacceptable from the point of view of correctness, if it weren't for the fact that to enable it, you have to define the semantics as undefined behavior which doesn't exclude using (c) for debug builds.
The most important feature of undefined behavior is that it allows you to choose the behavior that you want instead of hard-coding it into the program.
I disagree. I think, the choice is only there as long as you target a specific language implementation, or the very few of them which offer the choices you care about. If you're trying to write portable code, like we most often do in Boost, for example, you really don't have a choice and have to assume the behavior is really undefined. And this is the worst thing because it is a constant source of bugs and is not useful to the programmer. The ironic thing is that you can't even check for a possible overflow in portable C++ since "it doesn't happen" by the language rules and the compiler is allowed to subvert or completely discard your checks. Over the years I have grown a habit of avoiding signed integers where not genuinely needed. On the topic of performance gains, yes, there are some, but I'm not really convinced they are significant enough in general and can't be achieved by careful coding where truly needed.