Subject: Re: [boost] Current Guidance on Compiler Warnings?
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2018-11-27 16:18:10
On 11/26/2018 03:57 PM, Gavin Lambert via Boost wrote:
> On 27/11/2018 11:29, Steven Watanabe wrote:
>> signed integer overflow has undefined behavior.
>> unsigned integers wrap.Â This means that signed
>> integers give the compiler more scope for optimization
>> and/or runtime checks.
> I'm not aware of any compilers that actually do that, even in debug
>Â (Apart from ubsan, of course, but that also checks for unsigned
Sure, but that generates false positives. The
signed overflow check never generates false positives,
because it's always a bug.
> 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
(d) is the ideal solution, but is often infeasible. In
the case of integer addition, it means returning a type
which is large enough to hold any possible sum. Python
uses this approach with int and long, but it's not really
practical in C++ because of the performance implications.
(a) is what you get by using unsigned. I consider this
the worst possible choice because it combines the drawbacks
of (b) and (c) without any of their benefits. It is an
acceptable compromise if it is enabled by compiler
options (i.e. -fwrapv) rather than being required semantics.
(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
(c) is what safe languages use and is good from the standpoint
of correctness, but may have a significant performance penalty.
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.
> (Not that unintended wrapping of unsigned integers is much better, but
> at least it's less likely to summon Nyarlathotep.)
You're contradicting yourself. Extremely bizarre behavior
from UB is usually a result of the optimizer. If the optimizer
doesn't get involved, there's no real difference between the
behavior of signed overflow and unsigned overflow (assuming
that neither is intended).