C++ Logo

std-proposals

Advanced search

Re: [std-proposals] D3666R0 Bit-precise integers

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Thu, 4 Sep 2025 15:33:28 +0200
czw., 4 wrz 2025 o 14:51 David Brown <david.brown_at_[hidden]> napisał(a):
>
> On 04/09/2025 10:39, Marcin Jaczewski wrote:
> > czw., 4 wrz 2025 o 08:32 David Brown <david.brown_at_[hidden]> napisał(a):
> >>
> >>
> >>
> >> On 03/09/2025 21:09, Oliver Hunt wrote:
> >>>
> >>>
> >>>> On Sep 3, 2025, at 4:53 AM, David Brown <david.brown_at_[hidden]> wrote:
> >>>>>>
> >>>>>> Do we /need/ UB on signed arithmetic overflow? No. Do we /want/ UB
> >>>>>> on signed arithmetic overflow? Yes, IMHO. I am of the opinion that
> >>>>>> it makes no sense to add two negative numbers and end up with a
> >>>>>> positive number. There are very, very few situations where wrapping
> >>>>>> behaviour on signed integer arithmetic is helpful - making it
> >>>>>> defined as wrapping is simply saying that the language will pick a
> >>>>>> nonsensical result that can lead to bugs and confusion, limit
> >>>>>> optimisations and debugging, and cannot possibly give you a
> >>>>>> mathematically correct answer, all in the name of claiming to avoid
> >>>>>> undefined behaviour.
> >>>>> This as argument for unspecified or implementation defined behavior,
> >>>>> not introducing a brand new type, with *all* of the known security
> >>>>> issues of `int` (that we decided were not necessary for the
> >>>>> performance of unsigned integers).
> >>>>
> >>>> "int" does not, in itself, have "security issues". Incorrect
> >>>> programming can have security implications. Overflow - whether
> >>>> wrapping or UB, or anything else - is usually a bug in the code.
> >>>> Giving a fixed definition to the incorrect value does not magically
> >>>> fix the error in the code.
> >>>
> >>> No, Any new feature that introduces UB for no reason is a security
> >>> feature, for the same reason that creating new types that introduce
> >>> lifetime issues when used in a trivially obvious way (think: returning a
> >>> string_view).
> >>>
> >>
> >> Those are two wildly different things.
> >>
> >> Undefined behaviour is not in itself a security risk. /Incorrect/
> >> behaviour is a security risk. It does not matter whether a program bug
> >> has undefined behaviour, or defined and documented behaviour that is
> >> different from expected. If a program hits a bug in the code, it is now
> >> no longer doing what the programmer intended and predicted - and /that/
> >> is a security risk (for code that is relevant for security).
> >>
> >> It does not matter if "a + b" overflows and has undefined behaviour, or
> >> if "a + b" overflows and has defined but unexpected behaviour, such as
> >> suddenly jumping in value.
> >>
> >
> > To be devil's advocate, UB is worse as it is "viral", you not only get
> > the wrong value but
> > compiler can do unexpected things, like remove `if` that program tries
> > to use to detect overflow.
>
> /All/ incorrect code is viral in this sense. Once you've got a bug,
> things can go badly wrong very quickly. If your calculations don't give
> the correct value - the value that the programmer expects - then
> everything afterwards that assumes the code was correct, is in jeopardy.
> If you have a routine calculating the thrust rate for a rocket, and
> the calculations overflow, does it really matter if the next step is to
> assume that an overflow could never have happened, or if you run with a
> big negative thrust rate? (And if you had the foresight to check for
> negative thrust rates, you should have had the foresight to check for
> bad values before doing the overflowing calculations.)
>
> It is arguably the case that UB can lead to disaster a bit quicker, but
> getting meaningless well-defined results is not different in principle,
> and not significantly less bad in practice.
>

My point was that you could manually detect overflow if its not UB and
react accordingly.
UB sometimes makes it very hard to do some naive checks as they are UB itself
and can be removed by the compiler. And this is probably the biggest gripe that
people have with UB.
This mean we have diffrent types of "virality", first only cascade
with propagation of bad value
and second one UB, affects everything around,
like after `MAX_INT+1` compiler can delete the rest of the code in
function as its "impossible" for a program
to call this code legally.



> C11 tried to standardise two types of undefined behaviour - "bounded
> undefined behaviour" (which does not perform an "out-of-bounds store")
> and "critical undefined behaviour" (which might do so). This optional
> "Analyzability" annex has been ignored as impossible to implement and
> useless even if it were possible. All you need is one little integer
> calculation that is wrong, use it as the index of an array, and you can
> stomp randomly over anything in memory - full-blown critical UB from a
> simple coding error with fully defined behaviour at the point of the error.
>
>
> > This is why standart try to move to Erroneous Behavior in many cases.
> >
>
> And that is why I don't think there is much benefit in doing that. But
> it is good to encourage toolchains to check things when they can, so it
> has that benefit to it.
>
> > One thing for overflows to be "illegal" is that the program is
> > portable to other sizes of `int`.
> > Same program that works with `int` that has size of 16bit and does not
> > have UB, it will work
> > on machines that have 64bit int.
> >
>
> Code that is correct for a 16-bit int machine, with today's UB on
> overflow semantics, will be correct on a 64-bit int machine (or more
> realistically, a 32-bit int machine).
>
> The same would apply for erroneous behaviour on overflow - it would have
> no benefit or disadvantage, because hitting erroneous behaviour is as
> much a bug in your code as hitting UB.
>
> Code that is correct for a 16-bit int implementation that relies on
> wrapping behaviour, on the other hand, will be wrong on a 32-bit int
> machine.
>
>

This was my point here, if code works on 16bit without triggering UB
 then its will work the same on 64bit or 128bit.


I overall understand why UB is needed but I would not ignore the fact
that it has a lot of bad drawbacks.
And I would always check if this UB is really needed in the given case.

Received on 2025-09-04 13:33:42