Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

You can't have everything... where would you put it? -- Steven Wright


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?

<35ElI.498396$7Kb.383423@fx37.ams4>

  copy mid

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

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

On 08/05/2021 19:58, David Brown wrote:
> On 08/05/2021 16:38, Bart wrote:

> 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.

For the stuff I do, it can do exactly the same job as C, and generally
do it better.

Since C is a systems language, then so is mine, which is more up-to-date
and with less baggage (but with less mature compilers).

It's probably /more/ of a systems language as it's 'closer to the metal'
than C, and is much more specific in its targets. It directly has types
corresponding to what you find in hardware. And it has signed integer
overflow behaviour that matches what happens in its target hardware.

For a start, since consumer equipment has been 64 bits for most of this
century, its 'int' type defaults to 64 bits, while C's is still stuck at
32 bits (so you have to worry about overflows a bit more).

While both languages are languishing near the bottom end of the scale
when ranking high level languages, mine still manages literally hundreds
of small improvements over C. If anyone has some time, here's a list of
200 of them:

https://github.com/sal55/langs/blob/master/candm.md

I'm not asking anyone to like it or use it (support is not practical
anyway), but it's there, and is a real, working language.

Re: How to avoid an integer overflow?

<s77jou$5i9$1@z-news.wcss.wroc.pl>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: antis...@math.uni.wroc.pl - Sun, 9 May 2021 03:09 UTC

Bart <bc@freeuk.com> 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!
>
> > 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):

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

Look at following example:

#define AREF(p, i, lim) ((((i) < 0) || ((i) >= (lim)))?handle_erorr():(p)[(i)])

int
a_sum(int *p, int size) {
int i;
int res = 0;
for(i=0; i < size; i++) {
res += AREF(p, i, size);
}
return res;
}

This is proof of concept how one could try to ensure proper array
bounds checking in C. Of course better version would bundle array
and size and change AREF so that it extracts size from provided
data. Point of this example is that "obviously" all references
are in bounds and we would like no runtime overhead in such case.
With gcc 8.3.0 at -O2 this is indeed the case: we get the same
loop as if no bounds checking was present. It means that we can
use bounds checking macro for _every_ access and expect that
"obviously correct" cases will have no extra overhead due to
bounds checking code. In other words, only tricky cases will
remain.

What this has to do with signed overflow? This is the same
optimization that sometimes removes incorrect checks for overflow.
If find this optimization very important to writing safe and
efficient code. And I am not bothered if something funny
happens to my sum in case of overflow: when there is overflow
in sum my code is wrong anyway

> 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.

You somewhat do not get two important points:

- your code should be for humans to read

- C standard gives a lot of freedom to machine constructors, to
allow for efficient execution. Simple machine models are of
limited use to humans and could force inefficiency on machine
(this was experienced in PL/1, C learned from PL/1 mistakes).

--
Waldek Hebisch

Re: How to avoid an integer overflow?

<s77ljl$7ed$1@z-news.wcss.wroc.pl>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: antis...@math.uni.wroc.pl - Sun, 9 May 2021 03:40 UTC

Bart <bc@freeuk.com> 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.)

SSE instruction available in modern processors contain saturating
add. Also, with current standard FP double arithmetic can be used
for signed integer add, subtract and multiply. Alone it does not
make much sense. But compiler can effectively get some "free"
intructions by performing operations on vectors. I am not
aware of compiler actually performing such an optimization
and if done it would probably have rather small effect. But
modern compiler get efficient code by performing a lot of
optimizations which individually may have small effect, together
large number of small optimizations makes difference.

Concerning i16: this is actually problematic on modern machines.
Namely, corresponding x86 instruction is defined to preserve high
part of register which in some reasonably recent PC processors is
slow (Google "partial register stall"). 32-bit ARM (also models
designed few years ago) simply performs all integer operations
as 32-bits, you need separate instruction to discard high bits.
So if you insist you can get "true" 16-bit 2-complement arithmetic.
But as default it would be measurably slower than default promotions.

--
Waldek Hebisch

Re: How to avoid an integer overflow?

<KCPlI.524691$6dN1.414225@fx38.ams4>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sun, 9 May 2021 11:23 UTC

On 09/05/2021 04:09, antispam@math.uni.wroc.pl wrote:
> Bart <bc@freeuk.com> wrote:

>> Wouldn't it be great if C could make the same guarantee?
>
> Look at following example:
>
> #define AREF(p, i, lim) ((((i) < 0) || ((i) >= (lim)))?handle_erorr():(p)[(i)])
>
> int
> a_sum(int *p, int size) {
> int i;
> int res = 0;
> for(i=0; i < size; i++) {
> res += AREF(p, i, size);
> }
> return res;
> }
>
> This is proof of concept how one could try to ensure proper array
> bounds checking in C. Of course better version would bundle array
> and size and change AREF so that it extracts size from provided
> data.

Of course, let's do that instead.

(This is actually what I use with 'slices' in my language, which contain
a pointer and a length. Example:

proc start=
[]int a := (10,20,30,40)
println suma(a)
end

function suma(slice[]int a)int sum=
sum:=0
forall x in a do # or: for i in a.len do
sum+:=x # sum+:=a[i]
od
sum
end

It displays 100. I haven't used this much (hard to break old habits),
but was a straightforward addition to this level of language, so long as
it's seen purely as a view into an array or string.)

But otherwise you need to trust the programmer that 'size' in your
example is the length of the block of data pointed to by p. Then no
bounds checking is needed.

Adding bounds checking is awkward in C anyway; what ARE the bounds of p?
It might only be able to pass p as a fat pointer with bounds set by a
malloc call, which might be bigger than the row or slice that we want.

Point of this example is that "obviously" all references
> are in bounds and we would like no runtime overhead in such case.
> With gcc 8.3.0 at -O2 this is indeed the case: we get the same
> loop as if no bounds checking was present. It means that we can
> use bounds checking macro for _every_ access and expect that
> "obviously correct" cases will have no extra overhead due to
> bounds checking code. In other words, only tricky cases will
> remain.

My approach doesn't depend on adding lots of extra code, then requiring
59 optimising passes of gcc to tear it all down again.

> What this has to do with signed overflow? This is the same
> optimization that sometimes removes incorrect checks for overflow.

Usually there are no checks for overflow. For this you'd need special
overflow-checking versions of the int types, although then you'd need a
strategy as to what to do when detected.

>> 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.
>
> You somewhat do not get two important points:
>
> - your code should be for humans to read
>
> - C standard gives a lot of freedom to machine constructors, to
> allow for efficient execution. Simple machine models are of
> limited use to humans and could force inefficiency on machine
> (this was experienced in PL/1, C learned from PL/1 mistakes).

The model I propose IS simple. Further, it is simpler than that used by
C. Mine works like this, illustrated using a 3-bit signed type:

A: i3 u3

0 0 0 0 0
0 0 1 1 1
0 1 0 2 2
0 1 1 3 3
1 0 0 -4 4
1 0 1 -3 5
1 1 0 -2 6
1 1 1 -1 7

When A has the value 011 or 3, then incrementing turns it into 100, or
-4, ALWAYS.

When it has value 111 or -1, then incrementing turns it into 000 or 0,
always. Funnily this is the case where there are lost high order bits
(1000 -> 000) and it actually wraps, but no one thinks this is remarkable!

They are concerned only with the interpretation of the bits as shown in
column 2. Column 3 shows the interpretation as unsigned.

So that's my simple model. The model used by C is that, when A has the
value 011, and using column 2 to interpret that bit-value, then
incremementing A can cause ANYTHING to happen.

Except the actual behaviour follows my simple model enough to give a
false sense of security.

This makes predicting behaviour more difficult. You may not know, at
compile-time, the precise range of values of A. So you can't even allow
for the fact that, if overflow is undesirable, then you can detect that
because a positive value becomes negative.

Re: How to avoid an integer overflow?

<s7851p$ovi$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sun, 9 May 2021 08:04 UTC

On 08/05/2021 21:27, 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.
>
> 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.
>

The first rule of interactive programming is that you never trust the
input to the program - you always check it for sanity, validity, etc.
Code like this is fine if you have control of the input data and know it
is safe, or no one cares what happens if bad input is given. Otherwise,
it is broken the minute you make assumptions about the data that came in
without checking it.

That is not just about C - it is universal to all programming, and has
been known since Babbage's time:

"""
On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into
the machine wrong figures, will the right answers come out?' I am not
able rightly to apprehend the kind of confusion of ideas that could
provoke such a question.
"""

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

You need to learn what you are doing before trying to write real
programs. Is that such an unreasonable requirement?

Re: How to avoid an integer overflow?

<s786qr$4oe$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sun, 9 May 2021 08:34 UTC

On 08/05/2021 21:04, Bonita Montero wrote:
>> I told you, and showed you an example. ...
>
> The example has _nothing_ to do with what I did.

It used your code, and showed that it failed to work.

I copied your "bint32_t operator+" code into godbolt, fixed the mistakes
(the missing ".m_value" fields), then wrote some functions which clearly
call the code with values that overflow, but which did not lead to an
exception being thrown.

You clearly do not know how signed integer arithmetic is defined in C
and C++ (and more importantly, what aspects are /not/ defined). You
clearly have incorrect ideas about what compilers do with such code. It
would be better for you to listen and learn, and perhaps ask questions,
that to continue parading your ignorance and denying clear examples.
(This is not just hypothetical stuff on a hypothetical system - it's
real, as my example shows.)

Re: How to avoid an integer overflow?

<TLWlI.361555$MUKb.205348@fx17.ams4>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sun, 9 May 2021 19:30 UTC

On 09/05/2021 09:04, David Brown wrote:
> On 08/05/2021 21:27, Bart wrote:

> That is not just about C - it is universal to all programming, and has
> been known since Babbage's time:

> """
> On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into
> the machine wrong figures, will the right answers come out?' I am not
> able rightly to apprehend the kind of confusion of ideas that could
> provoke such a question.
> """

The wrong answers, if consistent, are better than a mystery prize which
is what C provides, or at least, which it constantly threatens according
to the people here (who like to use UB to beat people over the head with).

I've actually seen little evidence of bad things happening in real
programs that are not contrived examples.

When signed numbers overflow, you usually get the expected results.

And with the right compilers (eg. mine), that is what you do get.

>>
>
> You need to learn what you are doing before trying to write real
> programs. Is that such an unreasonable requirement?

How about the language making some effort too?

The standard 'int' type of C on most 64-bit computers is still 32 bits.
Using 64 bits would kick the can down the road far enough that overflow
is far less important.

Yet the C preprocessor does use 64 bits for CPP expressions; once again
it is more advanced than C itself! (The other one is having strictly
line-oriented if-elif-else-endif syntax with proper, mandatory block
delimiting.)

The following code ought to contain two examples of i32+i32 overflowing
at compile-time:

#include <stdio.h>
#include <stdint.h>

#define strtype(x) _Generic((x),\
int8_t: "i8",\
int16_t: "i16",\
int32_t: "i32",\
int64_t: "i64",\
uint8_t: "u8",\
uint16_t: "u16",\
uint32_t: "u32",\
uint64_t: "u64",\
default: "other")

int main(void) {
printf("%s\n",strtype(1000000000+2000000000));
printf("%d\n", (1000000000+2000000000));
}

But gcc and clang compilers, given suitable options, only detect the
second. Why is that, and why don't nasal daemons appear during the first?

Don't they bother actually doing the calculation?

Re: How to avoid an integer overflow?

<s79ggc$tbv$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Sun, 9 May 2021 20:25 UTC

On 09/05/2021 21:30, Bart wrote:
> On 09/05/2021 09:04, David Brown wrote:
>> On 08/05/2021 21:27, Bart wrote:
>
>> That is not just about C - it is universal to all programming, and has
>> been known since Babbage's time:
>
>> """
>> On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into
>> the machine wrong figures, will the right answers come out?'  I am not
>> able rightly to apprehend the kind of confusion of ideas that could
>> provoke such a question.
>> """
>
> The wrong answers, if consistent, are better than a mystery prize which
> is what C provides, or at least, which it constantly threatens according
> to the people here (who like to use UB to beat people over the head with).
>

If a language (or an implementation of it) guarantees particular
behaviour, then it is not wrong as far as the language and tools are
concerned - but it is still wrong as far as the programmer's
requirements. However, as the tools see a valid program and give valid
answers for them, they can do little to help find your mistake. When
these mistakes are undefined behaviour - known bad behaviour in the
language - tools have a chance of giving you help in finding the problems.

So a good C compiler might have instrumentation options like "trap on
overflow" or "sanitizers" for undefined behaviour that can be a good aid
in testing and fault-finding cases of overflowing signed integer
arithmetic. A Java tool, on the other hand, cannot give you that
because signed integer arithmetic is defined as wrapping.

Sometimes consistent handling of bad code can be useful in finding and
correcting errors. Other times it hides the errors so you don't know
they are there. It most certainly is not universally beneficial.

> I've actually seen little evidence of bad things happening in real
> programs that are not contrived examples.
>

That is because signed integer overflow very rarely happens, especially
with 32-bit (or bigger) ints. Thus optimising on the assumption that it
does not happen is a good thing.

> When signed numbers overflow, you usually get the expected results.

I don't expect results from signed overflows - but then, I program in C
when I write C code, rather than in some related concept of what I think
the language should mean. I think the same applies to a lot of C
programmers - though perhaps you and Bonita are exceptions. (Of course
we all have a risk of making mistakes in our code - but I find it
incomprehensible why someone would deliberately write code that they
know is wrong.)

>
> And with the right compilers (eg. mine), that is what you do get.
>
>>>
>>
>> You need to learn what you are doing before trying to write real
>> programs.  Is that such an unreasonable requirement?
>
>
> How about the language making some effort too?

How about letting the language be a language, and letting programmers
spend more time understanding what they are supposed to be doing and
less time complaining that the world doesn't fit their fantasies?

>
> The standard 'int' type of C on most 64-bit computers is still 32 bits.
> Using 64 bits would kick the can down the road far enough that overflow
> is far less important.

Overflow happens very rarely with 32-bit types. But you are free to use
64-bit integer types if you prefer.

>
> Yet the C preprocessor does use 64 bits for CPP expressions; once again
> it is more advanced than C itself!

I always find it amazing how you claim to have written a C compiler,
yet, constantly demonstrate that you have not read the specifications
for the language. (But to be clear - I still consider writing a
compiler for a sort-of-C language to be a very impressive feat.)

The nearest there is to "CPP expressions" would be "arithmetic constant
expressions" - and these are evaluated by exactly the same rules as C.

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

int64_t xx = 1000000000 * 1000000000;
int64_t yy = 1000000000000000000;

On x86, with 32-bit int, this gives:

xx:
.quad -1486618624
yy:
.quad 1000000000000000000

and a warning (even with no compiler options) about an overflow for
1000000000 * 1000000000.

> (The other one is having strictly
> line-oriented if-elif-else-endif syntax with proper, mandatory block
> delimiting.)
>
> The following code ought to contain two examples of i32+i32 overflowing
> at compile-time:
>
>  #include <stdio.h>
>  #include <stdint.h>
>
>  #define strtype(x) _Generic((x),\
>      int8_t: "i8",\
>      int16_t: "i16",\
>      int32_t: "i32",\
>      int64_t: "i64",\
>      uint8_t: "u8",\
>      uint16_t: "u16",\
>      uint32_t: "u32",\
>      uint64_t: "u64",\
>      default: "other")
>
>  int main(void) {
>      printf("%s\n",strtype(1000000000+2000000000));
>      printf("%d\n",       (1000000000+2000000000));
>  }
>
> But gcc and clang compilers, given suitable options, only detect the
> second. Why is that, and why don't nasal daemons appear during the first?

The first expression is used in a non-evaluating manner - only its type
is determined, but it is not evaluated. It is like sizeof() and
_Alignof in that way.

>
> Don't they bother actually doing the calculation?

No - because the language says they must not do it.

Re: How to avoid an integer overflow?

<XBYlI.457572$zV01.55874@fx49.ams4>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bart - Sun, 9 May 2021 21:36 UTC

On 09/05/2021 21:25, David Brown wrote:
> On 09/05/2021 21:30, Bart wrote:

>> Yet the C preprocessor does use 64 bits for CPP expressions; once again
>> it is more advanced than C itself!
>
> I always find it amazing how you claim to have written a C compiler,
> yet, constantly demonstrate that you have not read the specifications
> for the language. (But to be clear - I still consider writing a
> compiler for a sort-of-C language to be a very impressive feat.)
>
> The nearest there is to "CPP expressions" would be "arithmetic constant
> expressions" - and these are evaluated by exactly the same rules as C.
>
> <https://godbolt.org/z/YTWWh5s3q>
>
>
> int64_t xx = 1000000000 * 1000000000;
> int64_t yy = 1000000000000000000;
>
> On x86, with 32-bit int, this gives:
>
> xx:
> .quad -1486618624
> yy:
> .quad 1000000000000000000
>
> and a warning (even with no compiler options) about an overflow for
> 1000000000 * 1000000000.

By CPP I mean the C preprocessor. For example:

#if 1000000000*1000000000==1000000000000000000

Arithmetic done with the widest integer type, usually i64.

Re: How to avoid an integer overflow?

<87mtt38tru.fsf@nosuchdomain.example.com>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Keith Thompson - Sun, 9 May 2021 21:46 UTC

David Brown <david.brown@hesbynett.no> writes:
> On 09/05/2021 21:30, Bart wrote:
[...]
>> Yet the C preprocessor does use 64 bits for CPP expressions; once again
>> it is more advanced than C itself!
>
> I always find it amazing how you claim to have written a C compiler,
> yet, constantly demonstrate that you have not read the specifications
> for the language. (But to be clear - I still consider writing a
> compiler for a sort-of-C language to be a very impressive feat.)
>
> The nearest there is to "CPP expressions" would be "arithmetic constant
> expressions" - and these are evaluated by exactly the same rules as C.
[...]

I believe that Bart was referring to preprocessor arithmetic;
see N1570 6.10.1.

In a constant expression in a #if or #elif directive, signed
and unsigned integer types are treated as if they had the
same representation as intmax_t and uintmax_t, respectively.
(Those are 64 bits for most implementations, but of course they
could be bigger.)

Bart seems to think this is "more advanced" than expression
evaluation outside the preprocessor.

--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

Re: How to avoid an integer overflow?

<87im3r8t5q.fsf@nosuchdomain.example.com>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Keith Thompson - Sun, 9 May 2021 22:00 UTC

Bart <bc@freeuk.com> writes:
[...]
> By CPP I mean the C preprocessor. For example:
>
> #if 1000000000*1000000000==1000000000000000000
>
> Arithmetic done with the widest integer type, usually i64.

And again, you use your own invented terminology when the existing
terms defined in the C standard are unambiguous.

There's nothing in C called "i64" unless you define it yourself.
The standard says that preprocessor arithmetic is done using intmax_t
or uintmax_t, which are typically 64 bits. Why not just say that?

--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

Re: How to avoid an integer overflow?

<s7ann8$i5m$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Mon, 10 May 2021 07:35 UTC

> It used your code, and showed that it failed to work.

No, what you showes didn't use the function you sayed
that it doesn't work.

> I copied your "bint32_t operator+" code into godbolt, ...

But you don't used it.

> You clearly do not know how signed integer arithmetic is defined
> in C and C++ (and more importantly, what aspects are /not/ defined).

Tell me why a compiler should do any optimization wich yield
unexpected results with:
(left + right) ^ left

!!!

Re: How to avoid an integer overflow?

<s7ao9j$ma8$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Mon, 10 May 2021 07:44 UTC

If you want it idiot-proof, use this:
https://godbolt.org/z/Eo3vWzvbW

Re: How to avoid an integer overflow?

<s7aq5l$2vg$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bonita Montero - Mon, 10 May 2021 08:16 UTC

>> I copied your "bint32_t operator+" code into godbolt, ...

> But you don't used it.

Your a < 0 and b < 0 optimized away the usage of my code.
If you strip it my operator is used properly and there are
no optimizations about the wrap-around.

Re: How to avoid an integer overflow?

<s7as04$g3e$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Mon, 10 May 2021 08:48 UTC

On 10/05/2021 09:35, Bonita Montero wrote:
>> It used your code, and showed that it failed to work.
>
> No, what you showes didn't use the function you sayed
> that it doesn't work.
>
>> I copied your "bint32_t operator+" code into godbolt, ...
>
> But you don't used it.
>

Yes, I use it.

"a" and "b" are type "bint32_t", so when you add them, the "bint32_t
operator+" code is used.

If it makes things clearer for you, let's remove the int32_t() operator.
(I only put it in to save writing an operator < ).

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

Try removing the "operator +" (or changing it to "operator * "), and
you'll see the code won't compile. That is because the function is /used/.

>> You clearly do not know how signed integer arithmetic is defined
>> in C and C++ (and more importantly, what aspects are /not/ defined).
>
> Tell me why a compiler should do any optimization wich yield
> unexpected results with:
>     (left + right) ^ left
>
> !!!

Perhaps you are caught in a time-loop and stuck in the 1990's, before
code inlining and inter-procedural optimisations were common place?

/If/ the compiler generates a full stand-alone function for your
"operator +", then on the x86 it is highly unlikely to generate code
that is any different from your later /correct/ version that uses
uin32_t types for the addition.

On some processors, however, a compiler might generate an "add and trap
on overflow" instruction (which the x86 does not have, AFAIK). With
some compiler flags, the compiler might add an extra "trap on overflow"
check - it's the kind of flag people find useful in debugging and
fault-finding.

But more relevantly, as shown by this example, good compilers /don't/
use full stand-alone functions in cases like this. If they can use
partial inlining, propagation of constants or ranges, and other
inter-procedural optimisations to give smaller and faster object code,
then they will.

As people use template libraries more and more in C++ (and inline
functions in C headers, to a lesser extent), and link-time optimisations
are getting more common, this kind of manipulation by compilers is more
and more relevant.

And it is so /simple/ to write the code correctly. You managed it
yourself - just convert to uint32_t in the appropriate places. You even
did it already in the "carry" calculation. It is hard to understand why
you would therefore fail to do it correctly in the "signChange"
calculation - and even harder to understand why you defend such clear
errors.

Re: How to avoid an integer overflow?

<Nj7mI.234772$c2cf.177739@fx28.ams4>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bart - Mon, 10 May 2021 09:48 UTC

On 09/05/2021 23:00, Keith Thompson wrote:
> Bart <bc@freeuk.com> writes:
> [...]
>> By CPP I mean the C preprocessor. For example:
>>
>> #if 1000000000*1000000000==1000000000000000000
>>
>> Arithmetic done with the widest integer type, usually i64.
>
> And again, you use your own invented terminology when the existing
> terms defined in the C standard are unambiguous.
>

You flatter me. The term came from the first reasonable-looking google
hit, which was:

https://gcc.gnu.org/onlinedocs/cpp/If.html#If

and it says:

"The preprocessor calculates the value of expression. It carries out all
calculations in the widest integer type known to the compiler; on most
machines supported by GCC this is 64 bits. This is not the same rule as
the compiler uses to calculate the value of a constant expression, and
may give different results in some cases."

This also makes the same point as my post. (You might want to file a bug
report as to why these gcc docs don't use 'intmax_t' and 'uintmax_t'.)

> There's nothing in C called "i64" unless you define it yourself.
> The standard says that preprocessor arithmetic is done using intmax_t
> or uintmax_t, which are typically 64 bits. Why not just say that?

Because i64 and u64 are universally understood, and exactly match my
example. intmax_t and uintmax_t are not; they could be anything, and
might not have matched the point I was making in my example.

Besides, when someone is thinking of writing something like:

#if A == 0x7FFFFFFFFFFFFFFF

and wondering whether the values are going to be in range, they're not
going to be thinking about the vagaries of what exactly intmax_t might
be, they will have to KNOW that the types involved are 64-bit ints, or
i64 for short.

(FWIW, inside my C preprocessor, evaluations are done with routines like
this:

function evaladdexpr(int &sx)i64=
i64 x,y
....
return x
end

I believe sx is supposed to indicate to the caller whether the
expression is signed or not, but looking through the code, I don't seem
to have bothered.

Here, 'int' is an alias for 'int64' or 'i64'. I use one of the latter
when I need to emphasise that the width of the type is critical.)
)

Re: How to avoid an integer overflow?

<s7b4ht$fcj$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Mon, 10 May 2021 11:14 UTC

On 10/05/2021 11:48, Bart wrote:
> On 09/05/2021 23:00, Keith Thompson wrote:
>> Bart <bc@freeuk.com> writes:
>> [...]
>>> By CPP I mean the C preprocessor. For example:
>>>
>>> #if 1000000000*1000000000==1000000000000000000
>>>
>>> Arithmetic done with the widest integer type, usually i64.
>>
>> And again, you use your own invented terminology when the existing
>> terms defined in the C standard are unambiguous.
>>
>
> You flatter me. The term came from the first reasonable-looking google
> hit, which was:
>
>  https://gcc.gnu.org/onlinedocs/cpp/If.html#If
>
> and it says:
>
> "The preprocessor calculates the value of expression. It carries out all
> calculations in the widest integer type known to the compiler; on most
> machines supported by GCC this is 64 bits. This is not the same rule as
> the compiler uses to calculate the value of a constant expression, and
> may give different results in some cases."
>
> This also makes the same point as my post. (You might want to file a bug
> report as to why these gcc docs don't use 'intmax_t' and 'uintmax_t'.)

The C preprocessor applies to all C standards - C90 does not have
intmax_t, as that was introduced in C99.

>
>> There's nothing in C called "i64" unless you define it yourself.
>> The standard says that preprocessor arithmetic is done using intmax_t
>> or uintmax_t, which are typically 64 bits.  Why not just say that?
>
> Because i64 and u64 are universally understood, and exactly match my
> example.

i64 and u64 are your personal non-standard pointless renames for
standard, established and known C types int64_t and uin64_t. This is a
C newsgroup - use the C names. (I don't care what other languages might
have types with those names - in C, they could be used for local
variables or anything else.)

On old enough C compilers, these calculations will be 32 bit, not 64
bit. On a system that supports 128 bit integers, it will 128 bits.

TCC, for example, appears to do the calculations as 32 bit.

> intmax_t and uintmax_t are not; they could be anything, and
> might not have matched the point I was making in my example.

In a C newsgroup, intmax_t and uintmax_t should be understood, and match
exactly what the C standards say about these calculations - regardless
of any details of the compiler.

(Please don't take any of this as an endorsement of the rules C has for
this - as usual, I am trying to explain how things are, not how I think
they should have been.)

>
> Besides, when someone is thinking of writing something like:
>
>   #if A == 0x7FFFFFFFFFFFFFFF
>
> and wondering whether the values are going to be in range, they're not
> going to be thinking about the vagaries of what exactly intmax_t might
> be, they will have to KNOW that the types involved are 64-bit ints, or
> i64 for short.
>
> (FWIW, inside my C preprocessor, evaluations are done with routines like
> this:
>

What you do in your own implementation is not relevant. (Nor are any
other specific implementations.)

Re: How to avoid an integer overflow?

<Qq9mI.333120$tDk2.211030@fx06.ams4>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bart - Mon, 10 May 2021 12:12 UTC

On 10/05/2021 12:14, David Brown wrote:
> On 10/05/2021 11:48, Bart wrote:

> The C preprocessor applies to all C standards - C90 does not have
> intmax_t, as that was introduced in C99.
>
>>
>>> There's nothing in C called "i64" unless you define it yourself.
>>> The standard says that preprocessor arithmetic is done using intmax_t
>>> or uintmax_t, which are typically 64 bits.  Why not just say that?
>>
>> Because i64 and u64 are universally understood, and exactly match my
>> example.
>
> i64 and u64 are your personal non-standard pointless renames for
> standard, established and known C types int64_t and uin64_t.

Practically every other C application or library also defines its own
'pointless' names for such fixed-width types. You'd have to ask their
authors why they do that; it's not always because the program started
life before stdint.h was common, or because they are keen to have their
program work on C90.

My guess is that the stdint.h names are considered too unwieldy, too
ugly or too cluttery by some, with the important discriminating '32' or
'64' buried a little too deeply:

void fn(uint32_t s, uint64_t t, int32_t u);

versus:

void fn(u32 s, u64 t, i32 u);

Here's a quick survey of what various languages use for a 32-bit signed
integer type, arranged roughly by the length:

M i32
Odin i32
Rust i32
C# int
D int
Java int
Scala int
Go int32
Julia Int32
M int32
Nim int32
Swift Int32
C int32_t + #include <stdint.h> for these three
C int_fast32_t
C int_least32_t

(Some of those use only 'int', but they are guaranteed to be 32 bits
wide, so that C's 'int' can't be included here.)

I guess C wins the prize. Although I'm surprised more languages haven't
copied it more closely.

This is a
> C newsgroup - use the C names. (I don't care what other languages might
> have types with those names - in C, they could be used for local
> variables or anything else.)
>
> On old enough C compilers, these calculations will be 32 bit, not 64
> bit. On a system that supports 128 bit integers, it will 128 bits.
>
> TCC, for example, appears to do the calculations as 32 bit.

Are you sure? Tcc 0.9.27 is reasonably well-conforming, and uses the
same code-base for -m32 and -m64 invocations.

>
> What you do in your own implementation is not relevant. (Nor are any
> other specific implementations.)

My example showed that I clearly used 'i64' for evaluating cpp expressions.

Re: How to avoid an integer overflow?

<s7badi$u3g$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Mon, 10 May 2021 12:54 UTC

On 10/05/2021 14:12, Bart wrote:
> On 10/05/2021 12:14, David Brown wrote:
>> On 10/05/2021 11:48, Bart wrote:
>
>> The C preprocessor applies to all C standards - C90 does not have
>> intmax_t, as that was introduced in C99.
>>
>>>
>>>> There's nothing in C called "i64" unless you define it yourself.
>>>> The standard says that preprocessor arithmetic is done using intmax_t
>>>> or uintmax_t, which are typically 64 bits.  Why not just say that?
>>>
>>> Because i64 and u64 are universally understood, and exactly match my
>>> example.
>>
>> i64 and u64 are your personal non-standard pointless renames for
>> standard, established and known C types int64_t and uin64_t.
>
> Practically every other C application or library also defines its own
> 'pointless' names for such fixed-width types. You'd have to ask their
> authors why they do that; it's not always because the program started
> life before stdint.h was common, or because they are keen to have their
> program work on C90.

So because other people have done something counter-productive, you
think it's a good idea for you to follow suit? How about trying to be
/better/ than those you deride?

There may be good reasons for having different fixed-size types (perhaps
they are used to indicate particular uses in the code, perhaps they are
for compatibility with type names from other projects, etc.). And there
may be bad reasons for them, such as ignorance of <stdint.h> or
pointless dislikes of the format of the names.

>
> My guess is that the stdint.h names are considered too unwieldy, too
> ugly or too cluttery by some, with the important discriminating '32' or
> '64' buried a little too deeply:
>
>   void fn(uint32_t s, uint64_t t, int32_t u);
>
> versus:
>
>   void fn(u32 s, u64 t, i32 u);

Get yourself a better keyboard, or a bigger screen, and stop being so
pathetic.

>
> Here's a quick survey of what various languages use for a 32-bit signed
> integer type, arranged roughly by the length:
>

So what? This is a C newsgroup, and we are talking about C. It does
not matter in the slightest what other languages use, or whether they
have a concept of "32 bit signed integer" or not. In C, the type is
"int32_t". It is called that, because it simple and clearly says
exactly what the type is. It is the most sensible name for the time,
especially taking into account the history and established use.

>     C       int32_t       + #include <stdint.h> for these three
>     C       int_fast32_t
>     C       int_least32_t

Yes, C has additional sized types that give slightly different
guarantees and may be used in some types of code (particularly for
highly portable programming). They are not often needed, and it is
entirely appropriate that they are slightly more descriptive names.
Other languages are not as portable as C and thus such types are not needed.

>
> (Some of those use only 'int', but they are guaranteed to be 32 bits
> wide, so that C's 'int' can't be included here.)
>
> I guess C wins the prize. Although I'm surprised more languages haven't
> copied it more closely.
>

Different languages have different needs, and different preferences.
There's room for variety here.

>
>
>   This is a
>> C newsgroup - use the C names.  (I don't care what other languages might
>> have types with those names - in C, they could be used for local
>> variables or anything else.)
>>
>> On old enough C compilers, these calculations will be 32 bit, not 64
>> bit.  On a system that supports 128 bit integers, it will 128 bits.
>>
>> TCC, for example, appears to do the calculations as 32 bit.
>
> Are you sure? Tcc 0.9.27 is reasonably well-conforming, and uses the
> same code-base for -m32 and -m64 invocations.

I tested it with godbolt. And doing the calculations as 32 bit is as
conforming (AFAIK) as 64-bit or larger for C90.

>
>
>>
>> What you do in your own implementation is not relevant.  (Nor are any
>> other specific implementations.)
>
> My example showed that I clearly used 'i64' for evaluating cpp expressions.
>
>

Yes - and it is irrelevant.

Re: How to avoid an integer overflow?

<j2amI.753726$TXF.59212@fx04.ams4>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bart - Mon, 10 May 2021 12:54 UTC

On 10/05/2021 12:14, David Brown wrote:
> On 10/05/2021 11:48, Bart wrote:

> This is a
> C newsgroup - use the C names. (I don't care what other languages might
> have types with those names - in C, they could be used for local
> variables or anything else.)

You mean, like in C:

#include <stdio.h>

int main(void) {
int uint16_t=10, uint32_t=20, uint64_t;

uint64_t = uint16_t + uint32_t;
printf("%d\n",uint64_t);
}

I tried to do the same in mine (that is, use the names of BUILT-IN
STANDARD TYPES as identifiers), but I couldn't quite manage that neat trick.

I hadn't realised that you could do this in C:

{
#include <stdint.h>
}

and have those standard types only locally visible.

Re: How to avoid an integer overflow?

<AqamI.400286$PPIc.284851@fx15.ams4>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bart - Mon, 10 May 2021 13:20 UTC

On 10/05/2021 13:54, David Brown wrote:
> On 10/05/2021 14:12, Bart wrote:

>> Practically every other C application or library also defines its own
>> 'pointless' names for such fixed-width types. You'd have to ask their
>> authors why they do that; it's not always because the program started
>> life before stdint.h was common, or because they are keen to have their
>> program work on C90.
>
> So because other people have done something counter-productive,

I'm suggesting that if C had, perhaps from well before C99, short,
succinct and well-defined fixed-width type names, then an awful lot of
code would not have bothered to define their own variations, and it
would have been smaller and tidier.

Actually I did the same thing when I used to generate C code:

typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

The reason was to reduce the already bloated size of the generated code
(that had extra parentheses, casts etc), and make it somewhat more
readable if I had to ever look at it.

They also matched more directly the types in the original source which
could simply be generated verbatim instead of having to convert to
int64_t etc.

> How about trying to be
> /better/ than those you deride?

You mean, like creating a whole, better language? That's an idea...

>>   void fn(uint32_t s, uint64_t t, int32_t u);
>>
>> versus:
>>
>>   void fn(u32 s, u64 t, i32 u);
>
> Get yourself a better keyboard, or a bigger screen, and stop being so
> pathetic.

So I guess that readability doesn't matter for you.

> Different languages have different needs, and different preferences.
> There's room for variety here.

All the languages in my list had the same need: denote a type for a
signed integer of exactly 32 bits.

> Yes - and it is irrelevant.

It's good to see someone so focussed on one language that they will
entirely ignore influences, good or bad, from another.

I must have picked up i32 and u32 styles from somewhere, and thought
they made admirable short type names. I even typedefed them into C code
(when I wrote it manually), as I was fed up of writing 'unsigned long
long int' instead of u64, or writing #include <stdint.h> then still
needing to write uint64_t with that annoying shifted "_" in the middle.

Here's a suggestion for you: take one of your C source files, copy it,
and on the copy change all int32_t etc to i32 (or maybe int32, or try both).

Compare with the original; which one looks cleaner and clearer?

Re: How to avoid an integer overflow?

<s7bdcc$l14$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Mon, 10 May 2021 13:44 UTC

On 10/05/2021 15:20, Bart wrote:
> On 10/05/2021 13:54, David Brown wrote:
>> On 10/05/2021 14:12, Bart wrote:
>
>>> Practically every other C application or library also defines its own
>>> 'pointless' names for such fixed-width types. You'd have to ask their
>>> authors why they do that; it's not always because the program started
>>> life before stdint.h was common, or because they are keen to have their
>>> program work on C90.
>>
>> So because other people have done something counter-productive,
>
> I'm suggesting that if C had, perhaps from well before C99, short,
> succinct and well-defined fixed-width type names, then an awful lot of
> code would not have bothered to define their own variations, and it
> would have been smaller and tidier.

I like history - it's a hobby of mine. But I have never found such "how
would the world have been if /this/ had happened" speculations to be
particularly useful or enlightening. (Muta's desire to /change/
history, or re-live it in some weird way, is even stranger.)

If C had had size-specific types from its earlier conception (perhaps
since it was standardised), I expect there would be far fewer home-made
size-specific types. I think it is almost entirely irrelevant whether
those were named "int32_t", "i32", "signed word", "quadbyte", or
anything else.

>
> Actually I did the same thing when I used to generate C code:
>
>  typedef int8_t i8;
>  typedef int16_t i16;
>  typedef int32_t i32;
>  typedef int64_t i64;
>
>  typedef uint8_t u8;
>  typedef uint16_t u16;
>  typedef uint32_t u32;
>  typedef uint64_t u64;
>
> The reason was to reduce the already bloated size of the generated code
> (that had extra parentheses, casts etc), and make it somewhat more
> readable if I had to ever look at it.

You sometimes make relevant points about the weaknesses in C. Harping
on about such ridiculously small quibbles like this makes a mockery of that.

>
> They also matched more directly the types in the original source which
> could simply be generated verbatim instead of having to convert to
> int64_t etc.
>

Now, finally, you have a point that is meaningful. If you are
transcompiling from another language to C, then it might make sense to
use typenames in C that match those of the original language - /if/ the
types convey the same meaning.

>
>> How about trying to be
>> /better/ than those you deride?
>
> You mean, like creating a whole, better language? That's an idea...

No - I mean like writing standard C when you are writing C, and using C
terms when you are discussing C.

>
>>>    void fn(uint32_t s, uint64_t t, int32_t u);
>>>
>>> versus:
>>>
>>>    void fn(u32 s, u64 t, i32 u);
>>
>> Get yourself a better keyboard, or a bigger screen, and stop being so
>> pathetic.
>
> So I guess that readability doesn't matter for you.

Readability is vital to my coding, which is why I use standard names and
terms when they are available, and not silly pointless contractions.

>
>
> Here's a suggestion for you: take one of your C source files, copy it,
> and on the copy change all int32_t etc to i32 (or maybe int32, or try
> both).
>
> Compare with the original; which one looks cleaner and clearer?

The version with int32_t, uint32_t, etc., looks clearer - it's written
in C, not in some home-made mongrel language.

Re: How to avoid an integer overflow?

<s7bdlg$n90$1@dont-email.me>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: David Brown - Mon, 10 May 2021 13:49 UTC

On 10/05/2021 14:54, Bart wrote:
> On 10/05/2021 12:14, David Brown wrote:
>> On 10/05/2021 11:48, Bart wrote:
>
>> This is a
>> C newsgroup - use the C names.  (I don't care what other languages might
>> have types with those names - in C, they could be used for local
>> variables or anything else.)
>
> You mean, like in C:
>
>   #include <stdio.h>
>
>   int main(void) {
>       int uint16_t=10, uint32_t=20, uint64_t;
>
>       uint64_t = uint16_t + uint32_t;
>       printf("%d\n",uint64_t);
>   }

I'd venture to suggest that an identifier like "i8" might well be used
as a local variable. One ending in "_t" is unlikely to be used for
anything other than a type.

But of course no language or standard will stop people writing
intentional gibberish.

>
> I tried to do the same in mine (that is, use the names of BUILT-IN
> STANDARD TYPES as identifiers), but I couldn't quite manage that neat
> trick.
>
> I hadn't realised that you could do this in C:
>
>     {
>         #include <stdint.h>
>     }
>
> and have those standard types only locally visible.

You may or may not be able to do that. The standard headers are only
guaranteed to work the way they are specified if they are included
outside of declarations and definitions (7.1.2p4).

In particular, you will likely find that this can work locally inside a
function once, and then fail the next time as the include guards stop a
second inclusion having any effect.

Re: How to avoid an integer overflow?

<U8cmI.753737$TXF.62282@fx04.ams4>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Bart - Mon, 10 May 2021 15:18 UTC

On 10/05/2021 14:44, David Brown wrote:
> On 10/05/2021 15:20, Bart wrote:

>> The reason was to reduce the already bloated size of the generated code
>> (that had extra parentheses, casts etc), and make it somewhat more
>> readable if I had to ever look at it.
>
> You sometimes make relevant points about the weaknesses in C. Harping
> on about such ridiculously small quibbles like this makes a mockery of that.

How complicated does a /basic/ type have to be before even you start
complaining?

For this purpose, using stdint types exclusively pointlessly adds about
7.5% to the size of the generated code, but more importantly, makes it
even more cluttered than it already if you need to debug it.

>> They also matched more directly the types in the original source which
>> could simply be generated verbatim instead of having to convert to
>> int64_t etc.
>>
>
> Now, finally, you have a point that is meaningful. If you are
> transcompiling from another language to C, then it might make sense to
> use typenames in C that match those of the original language - /if/ the
> types convey the same meaning.

Actually, this isn't so importent, just more convenient; the same
function that generates a basic type name would work for both languages.

>>
>>> How about trying to be
>>> /better/ than those you deride?
>>
>> You mean, like creating a whole, better language? That's an idea...
>
> No - I mean like writing standard C when you are writing C, and using C
> terms when you are discussing C.

When discussing C then it is pointlessly pedantic to write out
"uint64_t" in full; neither of us are C compilers, and we're writing in
English not code. "u64" or "uint64" (or "unsigned 64 bits") are all
well-understood descriptions of that type.

(What did the forum look like before 1999, were people actually writing
out "unsigned long long int" in full to describe a 64-bit value?)

>> Compare with the original; which one looks cleaner and clearer?
>
> The version with int32_t, uint32_t, etc., looks clearer - it's written
> in C, not in some home-made mongrel language.

So you kind of home-made mongrel language is this fragment of code
written in:

struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};

You know, I can't see a single standard integer type in there. And I
can't guess those typedefs are. If I wanted to duplicated this struct to
use in an FFI, I would have my work cut out.

Here's what it could look like using not allowing plain types, but the
compact ones (version for Win64):

struct _stat {
u32 st_dev;
u16 st_ino;
u16 st_mode;
i16 st_nlink;
i16 st_uid;
i16 st_gid;
u32 st_rdev;
u32 st_size;
u64 st_atime;
u64 st_mtime;
u64 st_ctime;
};

Take a wild guess at what those types might mean.

Re: How to avoid an integer overflow?

<fa43353a-4dc2-4f49-8a00-3c8f94fb0a82n@googlegroups.com>

  copy mid

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

  copy link   Newsgroups: comp.lang.c
 by: Malcolm McLean - Mon, 10 May 2021 16:35 UTC

On Monday, 10 May 2021 at 14:44:55 UTC+1, David Brown wrote:
> On 10/05/2021 15:20, Bart wrote:
> > On 10/05/2021 13:54, David Brown wrote:
> >> On 10/05/2021 14:12, Bart wrote:
> >
> >>> Practically every other C application or library also defines its own
> >>> 'pointless' names for such fixed-width types. You'd have to ask their
> >>> authors why they do that; it's not always because the program started
> >>> life before stdint.h was common, or because they are keen to have their
> >>> program work on C90.
> >>
> >> So because other people have done something counter-productive,
> >
> > I'm suggesting that if C had, perhaps from well before C99, short,
> > succinct and well-defined fixed-width type names, then an awful lot of
> > code would not have bothered to define their own variations, and it
> > would have been smaller and tidier.
> I like history - it's a hobby of mine. But I have never found such "how
> would the world have been if /this/ had happened" speculations to be
> particularly useful or enlightening. (Muta's desire to /change/
> history, or re-live it in some weird way, is even stranger.)
>
> If C had had size-specific types from its earlier conception (perhaps
> since it was standardised), I expect there would be far fewer home-made
> size-specific types. I think it is almost entirely irrelevant whether
> those were named "int32_t", "i32", "signed word", "quadbyte", or
> anything else.
>
It's important that names are felicitous.
"int32_t" isn't too bad, bit it's rather clumsy to pronounce, and it has an underscore,
making it difficult to read and to type.
The term for a 16 bit type is "plyte" and a 32 bit type a "dyner", but they have never
really caught on. Technically a "byte" doesn't mean "8 bits" either, as we all know
on comp.lang.c.


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

Pages:123456789
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor