Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

You need tender loving care once a week - so that I can slap you into shape. -- Ellyn Mustard


devel / comp.lang.c / Re: How to avoid an integer overflow?

SubjectAuthor
* How to avoid an integer overflow?Oğuz
+* Re: How to avoid an integer overflow?David Brown
|+* Re: How to avoid an integer overflow?Ben Bacarisse
||+* Re: How to avoid an integer overflow?Richard Damon
|||`* Re: How to avoid an integer overflow?Ben Bacarisse
||| `* Re: How to avoid an integer overflow?Richard Damon
|||  `- Re: How to avoid an integer overflow?Ben Bacarisse
||+* Re: How to avoid an integer overflow?Oğuz
|||+* Re: How to avoid an integer overflow?Ben Bacarisse
||||+* Re: How to avoid an integer overflow?Oğuz
|||||+* Re: How to avoid an integer overflow?Richard Damon
||||||`- Re: How to avoid an integer overflow?Oğuz
|||||`* Re: How to avoid an integer overflow?Ben Bacarisse
||||| `- Re: How to avoid an integer overflow?Oğuz
||||`* Re: How to avoid an integer overflow?Keith Thompson
|||| `- Re: How to avoid an integer overflow?Ben Bacarisse
|||`- Re: How to avoid an integer overflow?Scott Lurndal
||`- Re: How to avoid an integer overflow?David Brown
|`* Re: How to avoid an integer overflow?Anton Shepelev
| `- Re: How to avoid an integer overflow?David Brown
+* Re: How to avoid an integer overflow?Bonita Montero
|`* Re: How to avoid an integer overflow?Bonita Montero
| `* Re: How to avoid an integer overflow?Bart
|  `* Re: How to avoid an integer overflow?Bonita Montero
|   `* Re: How to avoid an integer overflow?Bonita Montero
|    `* Re: How to avoid an integer overflow?Bart
|     +* Re: How to avoid an integer overflow?Bonita Montero
|     |+- Re: How to avoid an integer overflow?Bonita Montero
|     |`* Re: How to avoid an integer overflow?Bonita Montero
|     | `* Re: How to avoid an integer overflow?David Brown
|     |  `* Re: How to avoid an integer overflow?Bonita Montero
|     |   +* Re: How to avoid an integer overflow?Bart
|     |   |`- Re: How to avoid an integer overflow?Bonita Montero
|     |   `* Re: How to avoid an integer overflow?David Brown
|     |    `* Re: How to avoid an integer overflow?Bonita Montero
|     |     +- Re: How to avoid an integer overflow?Chris M. Thomasson
|     |     +* Re: How to avoid an integer overflow?Kaz Kylheku
|     |     |+* Re: How to avoid an integer overflow?Bart
|     |     ||`* Re: How to avoid an integer overflow?Kaz Kylheku
|     |     || `* Re: How to avoid an integer overflow?Bart
|     |     ||  +* Re: How to avoid an integer overflow?David Brown
|     |     ||  |`* Re: How to avoid an integer overflow?Bart
|     |     ||  | +- Re: How to avoid an integer overflow?Bart
|     |     ||  | +* Re: How to avoid an integer overflow?David Brown
|     |     ||  | |+* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||+- Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||+- Re: How to avoid an integer overflow?Kaz Kylheku
|     |     ||  | ||`* Re: How to avoid an integer overflow?David Brown
|     |     ||  | || `* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||  `* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   +* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |`* Re: How to avoid an integer overflow?Keith Thompson
|     |     ||  | ||   | `* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  +* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |+* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  ||+* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||`* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  ||| `* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||  +* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||  |+* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||  ||`* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||  || `- Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||  |`* Re: How to avoid an integer overflow?Kaz Kylheku
|     |     ||  | ||   |  |||  | `* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||  |  +* Re: How to avoid an integer overflow?Scott Lurndal
|     |     ||  | ||   |  |||  |  |`* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||  |  | `* Re: How to avoid an integer overflow?Tim Rentsch
|     |     ||  | ||   |  |||  |  |  `* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||  |  |   +- Re: How to avoid an integer overflow?Scott Lurndal
|     |     ||  | ||   |  |||  |  |   `- Re: How to avoid an integer overflow?Tim Rentsch
|     |     ||  | ||   |  |||  |  `* Re: How to avoid an integer overflow?Kaz Kylheku
|     |     ||  | ||   |  |||  |   `- Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||  `* Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   +* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||   |`* Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   | `* Re: How to avoid an integer overflow?Keith Thompson
|     |     ||  | ||   |  |||   |  `* Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   |   +- Re: How to avoid an integer overflow?james...@alumni.caltech.edu
|     |     ||  | ||   |  |||   |   `- Re: How to avoid an integer overflow?Keith Thompson
|     |     ||  | ||   |  |||   +* Re: How to avoid an integer overflow?Keith Thompson
|     |     ||  | ||   |  |||   |`* Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   | `* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||   |  `* Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   |   `* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||   |    `* Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   |     +* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||   |     |+* Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   |     ||`- Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||   |     |`* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||   |     | `* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||   |     |  +* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||   |     |  |`* Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||   |     |  | +- Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   |     |  | `- Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||   |     |  `* Re: How to avoid an integer overflow?antispam
|     |     ||  | ||   |  |||   |     |   +* Re: How to avoid an integer overflow?Kaz Kylheku
|     |     ||  | ||   |  |||   |     |   |`- Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||   |     |   +- Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  |||   |     |   `* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||   |     |    +* Re: How to avoid an integer overflow?Malcolm McLean
|     |     ||  | ||   |  |||   |     |    |`- Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  |||   |     |    `* Re: How to avoid an integer overflow?Kaz Kylheku
|     |     ||  | ||   |  |||   |     `* Re: How to avoid an integer overflow?Keith Thompson
|     |     ||  | ||   |  |||   `- Re: How to avoid an integer overflow?David Brown
|     |     ||  | ||   |  ||+- Re: How to avoid an integer overflow?Chris M. Thomasson
|     |     ||  | ||   |  ||`- Re: How to avoid an integer overflow?Kaz Kylheku
|     |     ||  | ||   |  |`* Re: How to avoid an integer overflow?Bart
|     |     ||  | ||   |  +- Re: How to avoid an integer overflow?Kaz Kylheku
|     |     ||  | ||   |  `* Re: How to avoid an integer overflow?Keith Thompson
|     |     ||  | ||   `- Re: How to avoid an integer overflow?Keith Thompson
|     |     ||  | |`- Re: How to avoid an integer overflow?Bart
|     |     ||  | `* Re: How to avoid an integer overflow?antispam
|     |     ||  +* Re: How to avoid an integer overflow?Richard Damon
|     |     ||  `- Re: How to avoid an integer overflow?Kaz Kylheku
|     |     |+- Re: How to avoid an integer overflow?Chris M. Thomasson
|     |     |`* Re: How to avoid an integer overflow?Bonita Montero
|     |     `* Re: How to avoid an integer overflow?David Brown
|     `- Re: How to avoid an integer overflow?David Brown
`* Re: How to avoid an integer overflow?Chris M. Thomasson

Pages:123456789
Re: How to avoid an integer overflow?

<s761bj$e2r$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16200&group=comp.lang.c++#16200

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sat, 8 May 2021 12:48 UTC

On 08/05/2021 14:10, Bonita Montero wrote:
>> Most optimising compilers will, at times, take advantage of knowing that
>> signed integer overflow is undefined behaviour and give smaller and
>> faster code on the assumption that it does not happen.
>
> Please tell me where I'm relying on signed oveflow !
> You haven't really read my code.
>

Your attempt at detecting sign change from adding two signed integers
relies on overflow being implemented as two's complement wrapping:

bool signChange = ((left + right) ^ left) >> 31;

Re: How to avoid an integer overflow?

<s761lf$kcd$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16201&group=comp.lang.c++#16201

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Sat, 8 May 2021 12:54 UTC

> Your attempt at detecting sign change from adding two signed integers
> relies on overflow being implemented as two's complement wrapping:
> bool signChange = ((left + right) ^ left) >> 31;

No, I'm not relying on overflow-wrapping here.
I'm only relying on twos-complement.

Re: How to avoid an integer overflow?

<V4wlI.303314$2A5.286607@fx45.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16202&group=comp.lang.c++#16202

  copy link   Newsgroups: comp.lang.c
 by: Branimir Maksimovic - Sat, 8 May 2021 13:10 UTC

On 2021-05-08, Bonita Montero <Bonita.Montero@gmail.com> wrote:
>> Your attempt at detecting sign change from adding two signed integers
>> relies on overflow being implemented as two's complement wrapping:
>> bool signChange = ((left + right) ^ left) >> 31;
>
> No, I'm not relying on overflow-wrapping here.
> I'm only relying on twos-complement.

Well, on twos complement machines signed overflow isn't problem,
problem is that sometimes compiler can be very smart and generate
different code ;)

--
current job title: senior software engineer
skills: x86 aasembler,c++,c,rust,go,nim,haskell...

press any key to continue or any other to quit...

Re: How to avoid an integer overflow?

<s7633h$fbj$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16203&group=comp.lang.c++#16203

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Sat, 8 May 2021 13:18 UTC

> Well, on twos complement machines signed overflow isn't problem,

That doesn't depend on if you're on a twos complement machine
or not if you can get into trouble relying on signed oveflows.

Re: How to avoid an integer overflow?

<s763er$n5d$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16204&group=comp.lang.c++#16204

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sat, 8 May 2021 13:24 UTC

On 08/05/2021 14:54, Bonita Montero wrote:
>> Your attempt at detecting sign change from adding two signed integers
>> relies on overflow being implemented as two's complement wrapping:
>>     bool     signChange = ((left + right) ^ left) >> 31;
>
> No, I'm not relying on overflow-wrapping here.
> I'm only relying on twos-complement.

So if left was 0x7fff'0000 and right was 0x0001'0001, you'd be quite
happy to have (left + right) evaluate to 0x1234'5678, just as long as
the result was stored in two's complement representation? No, I don't
think so. Your code is totally and completely dependent on the result
of the addition being evaluated with wrapping behaviour.

Re: How to avoid an integer overflow?

<s763vh$1c6$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16205&group=comp.lang.c++#16205

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Sat, 8 May 2021 13:33 UTC

>>> Your attempt at detecting sign change from adding two signed integers
>>> relies on overflow being implemented as two's complement wrapping:
>>>     bool     signChange = ((left + right) ^ left) >> 31;

>> No, I'm not relying on overflow-wrapping here.
>> I'm only relying on twos-complement.

> So if left was 0x7fff'0000 and right was 0x0001'0001, you'd be quite
> happy to have (left + right) evaluate to 0x1234'5678, just as long as
> the result was stored in two's complement representation? No, I don't
> think so. Your code is totally and completely dependent on the result
> of the addition being evaluated with wrapping behaviour.

My code is reliable on any machine with twos complement.

Re: How to avoid an integer overflow?

<uYwlI.445668$hcZe.117231@fx46.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16206&group=comp.lang.c++#16206

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sat, 8 May 2021 14:09 UTC

On 08/05/2021 14:33, Bonita Montero wrote:
>>>> Your attempt at detecting sign change from adding two signed integers
>>>> relies on overflow being implemented as two's complement wrapping:
>>>>      bool     signChange = ((left + right) ^ left) >> 31;
>
>>> No, I'm not relying on overflow-wrapping here.
>>> I'm only relying on twos-complement.
>
>> So if left was 0x7fff'0000 and right was 0x0001'0001, you'd be quite
>> happy to have (left + right) evaluate to 0x1234'5678, just as long as
>> the result was stored in two's complement representation?  No, I don't
>> think so.  Your code is totally and completely dependent on the result
>> of the addition being evaluated with wrapping behaviour.
>
> My code is reliable on any machine with twos complement.
>

This is the entire problem. You can't rely on C working as expected
because integer overflow will ALWAYS be undefined behaviour even when it
knows the hardware uses twos complement with well-defined overflow.

And some C compilers jump on that to allow them to do crazy things.

(Why does C do that? Presumably because SOME hardware in some far away
galaxy at one time didn't have well-defined behaviour, or at least was
different from twos complement, so it was easier for the language to say
it was undefined on ALL machines. Even now when all machines use twos
complement.)

Re: How to avoid an integer overflow?

<s76655$6g4$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16207&group=comp.lang.c++#16207

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Sat, 8 May 2021 14:10 UTC

> This is the entire problem. You can't rely on C working as expected
> because integer overflow will ALWAYS be undefined behaviour even when
> it knows the hardware uses twos complement with well-defined overflow.

There may be opportunties where the compiler will change the expected
behaviour, but there there isn't any.

Re: How to avoid an integer overflow?

<doxlI.1094727$8KY1.1004972@fx12.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16208&group=comp.lang.c++#16208

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sat, 8 May 2021 14:38 UTC

On 08/05/2021 13:24, David Brown wrote:
> On 08/05/2021 13:12, Bart wrote:

>> I understand the technical reasons. But I'm trying to see it from the
>> point of view of the programmer.
>
> As a programmer, I want to write my code in a clearly defined language
> that acts as a contract between the programmer and the compiler.

Deeming very common and harmless behaviour as undefined is a long way
from making it clearly defined!

> Then I
> want the compiler to generate the smallest and fastest object code it
> can (as well as give helpful messages when it sees something wrong). I
> expect the compiler to generate correct results from correct source code
> - equally, the compiler expects me to have written correct source code.
>
> Would you agree on that as a programmer viewpoint?

Using signed overflow as the basis for optimising due to UB is something
that ought to be optional; an extra level of optimisation.

At present, if you have an 8-bit signed char of 127, and add 1, you get
-128 with no UB. Same with a short value of 32767. Same with any integer
type until you get to a certain size that corresponds to plain int. Then
it's UB, unless you do it like this (when 'int' is i32):

int a = 0x7FFFFFFF;

a = (i64)a + 1;

or like this:

a = (u32)a + 1;

I think the behaviour of all these types should be consistent. Here's
how it works on a certain alternate systems language:

i8 a := i8.max
i16 b := i16.max
i32 c := i32.max
i64 d := i64.max
i128 e := i128.max

println a
println b
println c
println d
println e

println a+1
println b+1
println c+1
println d+1
println e+1

Output is guaranteed to be (whitespace added):

127
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727

128
32768
2147483648
-9223372036854775808
-170141183460469231731687303715884105728

Wouldn't it be great if C could make the same guarantee?

> We can disagree on the best choices for a language in regard to types,
> operations, overflow behaviour, etc. That's a different matter.
>
> C has its rules for integer promotion. It defines the wrapping
> behaviour for unsigned operations (on "unsigned int" and bigger - it
> does not define any arithmetic operations on smaller unsigned types).
> It makes overflow undefined for signed operations (again, there are no
> arithmetic operations at all on sizes smaller than int).
>
> As a C programmer, I am expected to know these rules. (They are not
> hard.) A C compiler reads the C source code, and assumes the programmer
> knows how to write C code - it does not attempt to read the programmer's
> mind and guess what he/she had intended to write.
>
> So from this programmer's prospective, at least, I expect the compiler
> to assume that my signed arithmetic can't overflow if that lets it
> generate better code or do better static analysis.
>
> And I think you'll have a hard time finding any non-programmer who
> thinks it makes sense to take a large positive number, add another
> positive number, and end up with a negative number. If you tell them,
> for example, that they are allowed to use six digits and positive and
> negative numbers, then ask what the result of adding 1 to 999999 should
> be, they'll say you can't do it. They will /not/ say -999999.

This is a machine not a human. Suppose the machine was a circular dial
with the numbers 0 to 99 evenly spaced c/w around the edge, and a dial
pointing to a value. You 'add 1' by stepping the dial one place
clockwise to the next marking.

If the dial is at 99, then 99+1 would be zero according to this machine,
unless you make it a LOT more complicated. Maybe there's a flag set
indicating it's gone from 99 to 0.

Now you want a similar machine to do signed. You can use exactly the
same machine, but just use an outer set of markings which start at 0
like unsigned, but only go up to +49 in c/w direction, and -50 in ac/w.

+49 is the same on both, but the next c/w marking for unsigned is +50,
and for signed it's -50.

Stepping from +49 to -50 is exactly the same operation as stepping from
+49 to +50; actually you can remove the markings, and it would still
work: the dial moves c/w through 3.6 degrees.

What C is saying, is that just /interpreting/ the new position of the
pointer according to the markings on band B instead of band A is
undefined behaviour, and it can use that to be able to move the dial to
some random position instead.

Re: How to avoid an integer overflow?

<s76805$ki8$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16209&group=comp.lang.c++#16209

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sat, 8 May 2021 14:42 UTC

On 08/05/2021 16:09, Bart wrote:
> On 08/05/2021 14:33, Bonita Montero wrote:
>>>>> Your attempt at detecting sign change from adding two signed integers
>>>>> relies on overflow being implemented as two's complement wrapping:
>>>>>      bool     signChange = ((left + right) ^ left) >> 31;
>>
>>>> No, I'm not relying on overflow-wrapping here.
>>>> I'm only relying on twos-complement.
>>
>>> So if left was 0x7fff'0000 and right was 0x0001'0001, you'd be quite
>>> happy to have (left + right) evaluate to 0x1234'5678, just as long as
>>> the result was stored in two's complement representation?  No, I don't
>>> think so.  Your code is totally and completely dependent on the result
>>> of the addition being evaluated with wrapping behaviour.
>>
>> My code is reliable on any machine with twos complement.
>>

No, it is not.

>
> This is the entire problem.

The problem is not caused by C or C compilers. It is caused by people
like Bonita who - contrary to everything they are told, including the
documentation of their compiler and the specifications of their language
- insist that C works how they want it to work instead of how it
actually works. It's stubborn, wilful ignorance.

> You can't rely on C working as expected

Of course you can. The trick is to expect C (and C compilers) to work
as they say they will, not as some people imagine they should.

> because integer overflow will ALWAYS be undefined behaviour even when it
> knows the hardware uses twos complement with well-defined overflow.
>

The behaviour is always undefined by the C standards - it might be
defined by some C compilers.

> And some C compilers jump on that to allow them to do crazy things.

Like give people more efficient results when they write correct code?
Yes, how crazy they are.

>
> (Why does C do that? Presumably because SOME hardware in some far away
> galaxy at one time didn't have well-defined behaviour, or at least was
> different from twos complement, so it was easier for the language to say
> it was undefined on ALL machines. Even now when all machines use twos
> complement.)

I know I've explained this to you a dozen times, and many other people
have done so as well. I'll not bother correcting you this time, since
expecting you to let the facts spoil a good rant definitely would be crazy.

Re: How to avoid an integer overflow?

<s7685r$lag$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16210&group=comp.lang.c++#16210

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Sat, 8 May 2021 14:45 UTC

>>> My code is reliable on any machine with twos complement.

> No, it is not.

There might be code where the compiler has the opportunity to change
from the expected behaviour, but there there isn't.

Re: How to avoid an integer overflow?

<JExlI.752035$TXF.323531@fx04.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16211&group=comp.lang.c++#16211

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sat, 8 May 2021 14:56 UTC

On 08/05/2021 15:38, Bart wrote:

> I think the behaviour of all these types should be consistent. Here's
> how it works on a certain alternate systems language:

> println a+1
> println b+1
> println c+1
> println d+1
> println e+1

> Output is guaranteed to be (whitespace added):
> 127
> 32767
> 2147483647
> 9223372036854775807
> 170141183460469231731687303715884105727
>
> 128
> 32768
> 2147483648
> -9223372036854775808
> -170141183460469231731687303715884105728

(Huh, it remove some of my whitespace!)

Actually, doing ++a then printing a instead of a+1 etc is a better way
of illustrating my earlier point. Then 'a' will have a value of -127. It
shows 128 here because expressions are evaluated using i64. By
incrementing the variables themselves, the last block will display for
a' b' c' d' e':

-128
-32768
-2147483648
-9223372036854775808
-170141183460469231731687303715884105728

If I try it in C:

int8_t a = 127;
int16_t b = 32767;
int32_t c = INT_MAX;
int64_t d = LLONG_MAX;

++a;
++b;
++c;
++d;

printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
printf("%lld\n", d);

I get something that looks promising:

-128
-32768
-2147483648
-9223372036854775808

Unfortunately, those last two increments are UB according to C. If the
results look correct, it is purely by luck.

(Except with my bcc compiler, where they are guaranteed.)

Re: How to avoid an integer overflow?

<s769e5$vj5$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16212&group=comp.lang.c++#16212

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sat, 8 May 2021 15:06 UTC

On 08/05/2021 16:10, Bonita Montero wrote:
>> This is the entire problem. You can't rely on C working as expected
>> because integer overflow will ALWAYS be undefined behaviour even when
>> it  knows the hardware uses twos complement with well-defined overflow.
>
> There may be opportunties where the compiler will change the expected
> behaviour, but there there isn't any.
>

Let's look at your code again, with obvious corrections:

inline
bint32_t operator +( bint32_t left, bint32_t right )
{ bool signChange = ((left.m_value + right.m_value) ^
left.m_value) >> 31;
bool carry = (uint32_t)left.m_value +
(uint32_t)right.m_value < (uint32_t)left.m_value;
bool overflow = signChange & !carry;
if( overflow )
throw range_error( "bint32_t add-overflow" );
return left.m_value + right.m_value;
}

When generating that function by itself, it is unlikely that there will
be much opportunity for optimisation by assuming there is no overflow
with current compilers, though certainly a hypothetical smart one could
do so.

But suppose - due to inlining and other analysis - that the compiler
knows other information about the function parameters. Perhaps, for
example, it knows that "right" is non-negative, and greater than "left".

Then it can reason that signChange can never be non-zero, as the
addition will not overflow in correctly written code. So no exception
will occur.

You can see gcc doing precisely that optimisation here:

<https://godbolt.org/z/EcExn86hK>

Re: How to avoid an integer overflow?

<s769pr$2mg$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16213&group=comp.lang.c++#16213

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Sat, 8 May 2021 15:12 UTC

> When generating that function by itself, it is unlikely that there will
> be much opportunity for optimisation by assuming there is no overflow
> with current compilers, though certainly a hypothetical smart one could
> do so.

How could such a compiler see a optimization-opportunity ?

> You can see gcc doing precisely that optimisation here:
> <https://godbolt.org/z/EcExn86hK>

My operator + code isn't used here.

Re: How to avoid an integer overflow?

<s76a40$4i1$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16214&group=comp.lang.c++#16214

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Sat, 8 May 2021 15:18 UTC

So please tell me: why should a compiler do any optimizations with
(left.m_value + right.m_value) ^ left.m_value
.... so that my code wouldn't work any more ?

Re: How to avoid an integer overflow?

<RoylI.94842$9L1.92845@fx05.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16215&group=comp.lang.c++#16215

  copy link   Newsgroups: comp.lang.c
 by: Richard Damon - Sat, 8 May 2021 15:47 UTC

On 5/8/21 7:12 AM, Bart wrote:
> On 08/05/2021 01:02, Kaz Kylheku wrote:
>> On 2021-05-07, Bart <bc@freeuk.com> wrote:
>
>>> Why should something work with i16 and not i32? It's inconsistent.
>>> Apparently integer overflow on i16 is fine!
>>
>> This is because if a signed integer expression has a type narrower
>> than int,
>> then its value is promoted to int.
>
> I understand the technical reasons. But I'm trying to see it from the
> point of view of the programmer.
>
> Adding 1 to the largest value of i16 or u32 is fine, it will wrap to the
> smallest value.

Maybe on the machine you are using. Not all machines do that.

>
> But it isn't fine for i32, or even i16 when your program runs on a
> machine where 'int' is i16 rather than i32.
>
> And the exact same operation is perfectly OK when run on the /same
> hardware/ using an alternative systems language, or even just assembly.

Because you are then using a tool that based on different guaranteees.

>
> So what's the deal with C?
>
> It gets more bizarre when you find it it runs just fine on most
> unoptimised C compilers too.

And this is because when you turn on the optimization (and not the
corresponding option that says that it needs to treat overflow as a
defined behavior) to optimize the operation of the code based on just
the guaranteed behavior. Since overflow operation is NOT guaranteed, and
you didn't tell it to make the added constraint that you want it to be,
it sees a condition that can never be false as long as you use onl
guaranteed behavior, so it can optimize it away.

In actuality, the compiler will do exactly what you want it to do, if
you tell it to do that. This means adding the option flags to tell the
compiler that you are counting on the beyond required by standard
behavior of the machine.

>
>> Well, the behavior is not defined by ISO C today and never has been
>> That is incontrovertible.
>
> Well, I disagree with that. I disagree more with some C compilers taking
> advantage of it by making /your/ program behave in a way you didn't intend.
>

Re: How to avoid an integer overflow?

<pEylI.245952$ON31.66255@fx23.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16217&group=comp.lang.c++#16217

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sat, 8 May 2021 16:04 UTC

On 08/05/2021 16:47, Richard Damon wrote:
> On 5/8/21 7:12 AM, Bart wrote:
>> On 08/05/2021 01:02, Kaz Kylheku wrote:
>>> On 2021-05-07, Bart <bc@freeuk.com> wrote:
>>
>>>> Why should something work with i16 and not i32? It's inconsistent.
>>>> Apparently integer overflow on i16 is fine!
>>>
>>> This is because if a signed integer expression has a type narrower
>>> than int,
>>> then its value is promoted to int.
>>
>> I understand the technical reasons. But I'm trying to see it from the
>> point of view of the programmer.
>>
>> Adding 1 to the largest value of i16 or u32 is fine, it will wrap to the
>> smallest value.
>
> Maybe on the machine you are using. Not all machines do that.

I assume you mean that they don't wrap signed integers when they
overflow. (As my examples were of when they do wrap in C.)

So, what machines don't do that? (Preferably ones designed within the
last 40 years.)

And of those, what do they do about overflow on unsigned integers?

(All the machines I've ever used, and ever likely to, use the same
machine instructions for add and subtract.)

Re: How to avoid an integer overflow?

<6NylI.80570$9F5.24892@fx43.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16218&group=comp.lang.c++#16218

  copy link   Newsgroups: comp.lang.c
 by: Richard Damon - Sat, 8 May 2021 16:13 UTC

On 5/8/21 12:04 PM, Bart wrote:
> On 08/05/2021 16:47, Richard Damon wrote:
>> On 5/8/21 7:12 AM, Bart wrote:
>>> On 08/05/2021 01:02, Kaz Kylheku wrote:
>>>> On 2021-05-07, Bart <bc@freeuk.com> wrote:
>>>
>>>>> Why should something work with i16 and not i32? It's inconsistent.
>>>>> Apparently integer overflow on i16 is fine!
>>>>
>>>> This is because if a signed integer expression has a type narrower
>>>> than int,
>>>> then its value is promoted to int.
>>>
>>> I understand the technical reasons. But I'm trying to see it from the
>>> point of view of the programmer.
>>>
>>> Adding 1 to the largest value of i16 or u32 is fine, it will wrap to the
>>> smallest value.
>>
>> Maybe on the machine you are using. Not all machines do that.
>
> I assume you mean that they don't wrap signed integers when they
> overflow. (As my examples were of when they do wrap in C.)
>
> So, what machines don't do that? (Preferably ones designed within the
> last 40 years.)
>
> And of those, what do they do about overflow on unsigned integers?
>
> (All the machines I've ever used, and ever likely to, use the same
> machine instructions for add and subtract.)
>

I've used some DSP processors where INT_MAX + 1 = INT_MAX, as they used
saturating arithmetic for signed values.

They had separate instructions for unsigned arithmetic.

It has been a while since I used it so I would need to look up the exact
part number.

Some Sign-Magnitude machines work in similar ways, those might just
barely meet your 40 year window, but were in use when C90 was being
worked on.

Re: How to avoid an integer overflow?

<20210508090846.719@kylheku.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16220&group=comp.lang.c++#16220

  copy link   Newsgroups: comp.lang.c
 by: Kaz Kylheku - Sat, 8 May 2021 16:20 UTC

On 2021-05-08, Bart <bc@freeuk.com> wrote:
> On 08/05/2021 01:02, Kaz Kylheku wrote:
>> On 2021-05-07, Bart <bc@freeuk.com> wrote:
>
>>> Why should something work with i16 and not i32? It's inconsistent.
>>> Apparently integer overflow on i16 is fine!
>>
>> This is because if a signed integer expression has a type narrower than int,
>> then its value is promoted to int.
>
> I understand the technical reasons. But I'm trying to see it from the
> point of view of the programmer.
>
> Adding 1 to the largest value of i16 or u32 is fine, it will wrap to the
> smallest value.

But in the i16 case it doesn't wrap. If the int type is wider than i16,
then the mathematical result 32768 is captured. If that is coerced back
to i16, then we get -32768 thanks to a particular implementation-defined
behavior which truncates the wider value to 16 bits.

> But it isn't fine for i32, or even i16 when your program runs on a
> machine where 'int' is i16 rather than i32.

You can do it yourself for i32 if you have an i64:

i = ((i64) i) + 1; // "manual promotion"

Now you have implementation-defined behavior, which is almost certainly
just straight 64->32 truncation.

It would be somewhat nice if you could just declare "in this region of
code, all integer ops are promoted to 64 bit".

> And the exact same operation is perfectly OK when run on the /same
> hardware/ using an alternative systems language, or even just assembly.
> So what's the deal with C?

Nope; assembly languages have provisions for trapping overflows. There
are just ways to ignore them.

C compilers for MIPS, for instance, use the "addu" instruction for
integer addition. Why? Because "add" generates overflow traps.

(It's kind of insane. Compiler writers are willing to optimize based on
the assumption of no overflow, but still pander to code that depends on
wrapping semantics by choosing instructions that wrap rather than trap.)

https://stackoverflow.com/questions/16634110/difference-between-add-and-addu

If you're writing MIPS code by hand, it behooves you to do your integer
additions with add, so the code doesn't silently continue with a wrapped
result.

> It gets more bizarre when you find it it runs just fine on most
> unoptimised C compilers too.
>
>> Well, the behavior is not defined by ISO C today and never has been
>> That is incontrovertible.
>
> Well, I disagree with that. I disagree more with some C compilers taking
> advantage of it by making /your/ program behave in a way you didn't intend.

Disagree? What version of ISO C do you think defined signed overflow?

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

Re: How to avoid an integer overflow?

<s76n0g$6ql$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16221&group=comp.lang.c++#16221

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sat, 8 May 2021 18:58 UTC

On 08/05/2021 16:38, Bart wrote:
> On 08/05/2021 13:24, David Brown wrote:
>> On 08/05/2021 13:12, Bart wrote:
>
>>> I understand the technical reasons. But I'm trying to see it from the
>>> point of view of the programmer.
>>
>> As a programmer, I want to write my code in a clearly defined language
>> that acts as a contract between the programmer and the compiler.
>
> Deeming very common and harmless behaviour as undefined is a long way
> from making it clearly defined!

I'm sorry, you see to have different definitions of "common", "harmless"
and "clearly defined".

Integer overflow is /not/ common - especially not in the 32-bit int
world. Numbers over 2 billion are rarely used.

Expecting wrapping behaviour for correct behaviour is /not/ common -
adding two large positive numbers and expecting the result to be
negative is utterly absurd. It rarely matters whether this behaviour is
defined or not - if it occurs, the program is broken. Overflows are
/not/ harmless, defined or not.

And the fact that in C, signed integer overflows are undefined behaviour
is not exactly a secret - it is quite simple to understand, and well-known.

>
>> Then I
>> want the compiler to generate the smallest and fastest object code it
>> can (as well as give helpful messages when it sees something wrong).  I
>> expect the compiler to generate correct results from correct source code
>> - equally, the compiler expects me to have written correct source code.
>>
>> Would you agree on that as a programmer viewpoint?
>
> Using signed overflow as the basis for optimising due to UB is something
> that ought to be optional; an extra level of optimisation.
>

Almost all compilers I have used - and that is quite a few - have needed
specific flags to enable optimisation of any sort.

> At present, if you have an 8-bit signed char of 127, and add 1, you get
> -128 with no UB.

Not necessarily - it depends on the system. The signed char gets
promoted to int, which is guaranteed to be big enough to hold 127 + 1
which is 128. If you then convert back to a signed char, you will
likely get -128 but that is implementation dependent. But as you say,
there is no undefined behaviour (unless signed char is the same size as
int, which is the case on some 16-bit CHAR systems).

> Same with a short value of 32767.

And you make the same mistakes here.

C does not have a definition of adding 1 (or doing any arithmetic) on
types smaller than int or unsigned int.

> Same with any integer
> type until you get to a certain size that corresponds to plain int. Then
> it's UB, unless you do it like this (when 'int' is i32):

Look, we all know this stuff. I think even Bonita knows it - she simply
denies it because that would mean admitting a mistake, and she'd rather
be thought an arrogant fool than admit to getting something wrong.

And lots of us have opinions as to whether we /like/ the integer
promotions, the design choices for overflow or wrapping behaviour, and
other related aspects. So we can skip the repetition.

And we can skip your self-congratulatory description of what you call
your "systems language". (Hint - a personal language is not a "systems
language". You might find it useful, but no one else does. And no one
is remotely impressed by how great /you/ think it is - it would be
rather ridiculous if language definition didn't fit exactly the rules
/you/ think are ideal.)

It really doesn't matter that I agree with some aspects of what you
might prefer in a language, and disagree with others. (Or that I think
some aspects of your personal language are rather nice.)

>
> Wouldn't it be great if C could make the same guarantee?
>

No. C is C. I have /my/ preferences for a language, you have /your/
preferences. While I have no doubt at all that /my/ preferences are the
best, I don't expect others to agree with them and I don't expect
languages to follow /my/ preferences.

>
>> We can disagree on the best choices for a language in regard to types,
>> operations, overflow behaviour, etc.  That's a different matter.
>>
>> C has its rules for integer promotion.  It defines the wrapping
>> behaviour for unsigned operations (on "unsigned int" and bigger - it
>> does not define any arithmetic operations on smaller unsigned types).
>> It makes overflow undefined for signed operations (again, there are no
>> arithmetic operations at all on sizes smaller than int).
>>
>> As a C programmer, I am expected to know these rules.  (They are not
>> hard.)  A C compiler reads the C source code, and assumes the programmer
>> knows how to write C code - it does not attempt to read the programmer's
>> mind and guess what he/she had intended to write.
>>
>> So from this programmer's prospective, at least, I expect the compiler
>> to assume that my signed arithmetic can't overflow if that lets it
>> generate better code or do better static analysis.
>>
>> And I think you'll have a hard time finding any non-programmer who
>> thinks it makes sense to take a large positive number, add another
>> positive number, and end up with a negative number.  If you tell them,
>> for example, that they are allowed to use six digits and positive and
>> negative numbers, then ask what the result of adding 1 to 999999 should
>> be, they'll say you can't do it.  They will /not/ say -999999.
>
> This is a machine not a human.

No, but /I/ am. (Well, I pretend to be one in my spare time :-) )

And I am a mathematician by education. C int's are a better model for
real mathematical integers by having undefined overflow than if they
were wrapping.

> Suppose the machine was a circular dial
> with the numbers 0 to 99 evenly spaced c/w around the edge, and a dial
> pointing to a value. You 'add 1' by stepping the dial one place
> clockwise to the next marking.

Yes - but that is modular arithmetic, not integer arithmetic. It's a
different thing. Unsigned integers in C use modular arithmetic. Signed
integers don't.

>
> If the dial is at 99, then 99+1 would be zero according to this machine,
> unless you make it a LOT more complicated. Maybe there's a flag set
> indicating it's gone from 99 to 0.
>
> Now you want a similar machine to do signed. You can use exactly the
> same machine, but just use an outer set of markings which start at 0
> like unsigned, but only go up to +49 in c/w direction, and -50 in ac/w.
>
> +49 is the same on both, but the next c/w marking for unsigned is +50,
> and for signed it's -50.
>

Sure, with enough convoluted and unrealistic explanations you can invent
something that is not programming but which works the way you would like
C to work.

Personally, I prefer a language that says if you add a positive value to
something, the thing gets bigger. And I prefer that when you try to
write something silly that makes no sense, the compiler doesn't try to
make sense of it or go out of its way to give you something that is
utterly nonsensical just because it would be consistent. (I'm fine with
checked languages that give a run-time error on overflow, or that have
integer types that grow as needed.)

> Stepping from +49 to -50 is exactly the same operation as stepping from
> +49 to +50; actually you can remove the markings, and it would still
> work: the dial moves c/w through 3.6 degrees.
>
> What C is saying, is that just /interpreting/ the new position of the
> pointer according to the markings on band B instead of band A is
> undefined behaviour, and it can use that to be able to move the dial to
> some random position instead.
>

No, what C is saying is that you can have a reasonable model of real
integers with efficient code, but you have to understand that on a
limited machine the model is limited.

Re: How to avoid an integer overflow?

<s76n8l$6ql$2@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16223&group=comp.lang.c++#16223

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sat, 8 May 2021 19:02 UTC

On 08/05/2021 17:18, Bonita Montero wrote:
> So please tell me: why should a compiler do any optimizations with
>     (left.m_value + right.m_value) ^ left.m_value
> ... so that my code wouldn't work any more ?

I told you, and showed you an example. If you are still in deniable
about it, that's your problem.

Re: How to avoid an integer overflow?

<s76nc9$9lq$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16224&group=comp.lang.c++#16224

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Sat, 8 May 2021 19:04 UTC

> I told you, and showed you an example. ...

The example has _nothing_ to do with what I did.

Re: How to avoid an integer overflow?

<0DBlI.271496$qHh9.32882@fx18.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16225&group=comp.lang.c++#16225

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sat, 8 May 2021 19:27 UTC

On 08/05/2021 19:58, David Brown wrote:
> On 08/05/2021 16:38, Bart wrote:
>> On 08/05/2021 13:24, David Brown wrote:
>>> On 08/05/2021 13:12, Bart wrote:
>>
>>>> I understand the technical reasons. But I'm trying to see it from the
>>>> point of view of the programmer.
>>>
>>> As a programmer, I want to write my code in a clearly defined language
>>> that acts as a contract between the programmer and the compiler.
>>
>> Deeming very common and harmless behaviour as undefined is a long way
>> from making it clearly defined!
>
> I'm sorry, you see to have different definitions of "common", "harmless"
> and "clearly defined".
>
> Integer overflow is /not/ common - especially not in the 32-bit int
> world. Numbers over 2 billion are rarely used.

Try this program:

int a,b,c;

scanf("%d",&a);
scanf("%d",&b);

c=a+b;

printf("%d + %d => %d\n",a,b,c);

The c=a+b line will exhibit undefined behaviour depending on the values
the user inputs.

This is not a very high level language with advanced, auto-widening
numeric types. It's a crude systems language. It should not a surprising
to anyone using such language, that there are so only so many bits
available for arithmetic, and that sometimes higher order bits will be lost.

I can remove the UB by casting a and b to unsigned, but the result of
adding 2000000000 and 1000000000 will still be -1294967296. In that
case, why the need to bother with the casts?

Maybe we can do arithmetic with unsigned, as that is better behaved with
no UB, with none of the nonsense results you get with signed:

unsigned int a,b,c;

scanf("%u",&a);
scanf("%u",&b);

c=a-b;

printf("%u - %u => %u\n",a,b,c);

Now, if I enter 1 and 2, I get the sensible value of 4294967295! If I go
back to "+", and enter 3000000000 and 2000000000, the result is 705032704.

People need to know about such problems in a lower level language,
rather than try and pretend that it doesn't happen.

Re: How to avoid an integer overflow?

<a2e2aad1-719d-46e8-9ce9-66a138231f24n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16226&group=comp.lang.c++#16226

  copy link   Newsgroups: comp.lang.c
 by: Malcolm McLean - Sat, 8 May 2021 20:02 UTC

On Saturday, 8 May 2021 at 20:28:07 UTC+1, Bart wrote:
> On 08/05/2021 19:58, David Brown wrote:
> > On 08/05/2021 16:38, Bart wrote:
> >> On 08/05/2021 13:24, David Brown wrote:
> >>> On 08/05/2021 13:12, Bart wrote:
> >>
> >>>> I understand the technical reasons. But I'm trying to see it from the
> >>>> point of view of the programmer.
> >>>
> >>> As a programmer, I want to write my code in a clearly defined language
> >>> that acts as a contract between the programmer and the compiler.
> >>
> >> Deeming very common and harmless behaviour as undefined is a long way
> >> from making it clearly defined!
> >
> > I'm sorry, you see to have different definitions of "common", "harmless"
> > and "clearly defined".
> >
> > Integer overflow is /not/ common - especially not in the 32-bit int
> > world. Numbers over 2 billion are rarely used.
>
>
> Maybe we can do arithmetic with unsigned, as that is better behaved with
> no UB, with none of the nonsense results you get with signed:
>
In real programs, number represent things.
Once we were writing a video game where the game world was a power of two
of a power of two cells in each direction. So we could use hardware
integer wrapping as a free modulus operation. However that's rare, you very
seldom want to calculate the sum of two numbers modulus the hardware
integer size.
If a number overflows, then it usually means that the user is trying to run
a calculation on a dataset which is too large for the system to support,
or that his input files have been corrupted. In either case, it's better to
usually terminate the program with an error message than to plough on.

Re: How to avoid an integer overflow?

<20210508150655.455@kylheku.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=16235&group=comp.lang.c++#16235

  copy link   Newsgroups: comp.lang.c
 by: Kaz Kylheku - Sat, 8 May 2021 22:07 UTC

On 2021-05-08, Bart <bc@freeuk.com> wrote:
> Try this program:
>
> int a,b,c;
>
> scanf("%d",&a);
> scanf("%d",&b);
>
> c=a+b;
>
> printf("%d + %d => %d\n",a,b,c);
>
> The c=a+b line will exhibit undefined behaviour depending on the values
> the user inputs.

ITYM, the scanf call will exhibit undefined behavior depending on the
values the user inputs. :)


devel / comp.lang.c / Re: How to avoid an integer overflow?

Pages:123456789
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor