November 21, 2014
On Fri, 21 Nov 2014 11:17:06 -0300
Ary Borenszweig via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

> "This bug can manifest itself for arrays whose length (in elements) is 2^30 or greater (roughly a billion elements)"
> 
> How often does that happen in practice?
once in almost ten years is too often, as for me. i think that the answer must be "never". either no bug, or the code is broken. and one of the worst code is the code that "works most of the time", but still broken.


November 21, 2014
On Fri, 21 Nov 2014 14:37:39 +0000
Araq via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

> "broken" is not a black-white thing. "Works most of the time" surely is much more useful than "doesn't work". Otherwise you would throw away your phone the first time you get a busy signal.
"works most of the time" is the worst thing: the bug can be hidden for decades and then suddenly blows up stright into your face, making you wonder what happens with "good code".

i will chose the code which "doesn't work" over "works most of the time" one: the first has a clearly visible problem, and the former has a carefully hidden problem. i prefer visible problems.

btw, your phone example is totally wrong, 'case "busy" is a well-defined state. i for sure will throw the phone away if the phone accepts only *some* incoming calls and silently ignores some others (without me explicitly telling it to do so, of course). that's like a code that "works most of the time". but not in that time when they phoning you to tell that your house is on fire.


November 21, 2014
On Friday, 21 November 2014 at 13:59:08 UTC, ketmar via Digitalmars-d wrote:

> any code which does something like `if (a-b < 0)` is broken. it

Modify it: https://github.com/D-Programming-Language/druntime/blob/master/src/core/checkedint.d

Modify method: subu(uint ...) or subu(ulong ...)
if(x<y)
return y -x ;
else
 return x -y;

It will be not broken.
November 21, 2014
On Fri, 21 Nov 2014 14:55:45 +0000
FrankLike via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

> On Friday, 21 November 2014 at 13:59:08 UTC, ketmar via Digitalmars-d wrote:
> 
> > any code which does something like `if (a-b < 0)` is broken. it
> 
> Modify it: https://github.com/D-Programming-Language/druntime/blob/master/src/core/checkedint.d
> 
> Modify method: subu(uint ...) or subu(ulong ...)
> if(x<y)
> return y -x ;
> else
>   return x -y;
> 
> It will be not broken.
and it will not do the same anymore too. it's not a fix at all.


November 21, 2014
On Friday, 21 November 2014 at 15:13:22 UTC, ketmar via Digitalmars-d wrote:


> and it will not do the same anymore too. it's not a fix at all.

But  it is a part of bugs.
Sure,bug  which  is  in  mixing sign and  unsign  values should  be  fix.
November 21, 2014
On Friday, 21 November 2014 at 04:53:38 UTC, Walter Bright wrote:
> On 11/20/2014 7:11 PM, Walter Bright wrote:
>> On 11/20/2014 3:25 PM, bearophile wrote:
>>> Walter Bright:
>>>
>>>> If that is changed to a signed type, then you'll have a same-only-different
>>>> set of subtle bugs,
>>>
>>> This is possible. Can you show some of the bugs, we can discuss them, and see if
>>> they are actually worse than the current situation.
>>
>> All you're doing is trading 0 crossing for 0x7FFFFFFF crossing issues, and
>> pretending the problems have gone away.
>
> BTW, granted the 0x7FFFFFFF problems exhibit the bugs less often, but paradoxically this can make the bug worse, because then it only gets found much, much later in supposedly tested & robust code.
>
> 0 crossing bugs tend to show up much sooner, and often immediately.


You're missing the point here. The problem is that people are using 'uint' as if it were a positive integer type.

Suppose  D had a type 'natint', which could hold natural numbers in the range 0..uint.max.  Sounds like 'uint', right? People make the mistake of thinking that is what uint is. But it is not.

How would natint behave, in the type system?

typeof (natint - natint)  ==  int     NOT natint  !!!

This would of course overflow if the result is too big to fit in an int. But the type would be correct.  1 - 2 == -1.

But

typeof (uint - uint ) == uint.

The bit pattern is identical to the other case. But the type is wrong.

It is for this reason that uint is not appropriate as a model for positive integers. Having warnings about mixing int and uint operations in relational operators is a bit misleading, because mixing signed and unsigned is not usually the real problem. Instead, those warnings a symptom of a type system mistake.

You are quite right in saying that with a signed length, overflows can still occur. But, those are in principle detectable. The compiler could add runtime overflow checks for them, for example. But the situation for unsigned is not fixable, because it is a problem with the type system.


By making .length unsigned, we are telling people that if .length is
used in a subtraction expression, the type will be wrong.

It is the incorrect use of the type system that is the underlying problem.



November 21, 2014
On Friday, 21 November 2014 at 15:36:02 UTC, Don wrote:
> On Friday, 21 November 2014 at 04:53:38 UTC, Walter Bright wrote:
>> On 11/20/2014 7:11 PM, Walter Bright wrote:
>>> On 11/20/2014 3:25 PM, bearophile wrote:
>>>> Walter Bright:
>>>>
>>>>> If that is changed to a signed type, then you'll have a same-only-different
>>>>> set of subtle bugs,
>>>>
>>>> This is possible. Can you show some of the bugs, we can discuss them, and see if
>>>> they are actually worse than the current situation.
>>>
>>> All you're doing is trading 0 crossing for 0x7FFFFFFF crossing issues, and
>>> pretending the problems have gone away.
>>
>> BTW, granted the 0x7FFFFFFF problems exhibit the bugs less often, but paradoxically this can make the bug worse, because then it only gets found much, much later in supposedly tested & robust code.
>>
>> 0 crossing bugs tend to show up much sooner, and often immediately.
>
>
> You're missing the point here. The problem is that people are using 'uint' as if it were a positive integer type.
>
> Suppose  D had a type 'natint', which could hold natural numbers in the range 0..uint.max.  Sounds like 'uint', right? People make the mistake of thinking that is what uint is. But it is not.
>
> How would natint behave, in the type system?
>
> typeof (natint - natint)  ==  int     NOT natint  !!!
>
> This would of course overflow if the result is too big to fit in an int. But the type would be correct.  1 - 2 == -1.
>

So if i is a natint the expression i-- would change the type of variable i on the fly to int ?
November 21, 2014
On Fri, Nov 21, 2014 at 03:36:01PM +0000, Don via Digitalmars-d wrote: [...]
> Suppose  D had a type 'natint', which could hold natural numbers in the range 0..uint.max.  Sounds like 'uint', right? People make the mistake of thinking that is what uint is. But it is not.
> 
> How would natint behave, in the type system?
> 
> typeof (natint - natint)  ==  int     NOT natint  !!!

Wrong. (uint.max - 0) == uint.max, which is of type uint. If you interpret it as int, you get a negative number, which is wrong. So your proposal breaks uint in even worse ways, in that now subtracting a smaller number from a larger number may overflow, whereas it wouldn't before. So that fixes nothing, you're just shifting the problem somewhere else.


T

-- 
Too many people have open minds but closed eyes.
November 21, 2014
On 11/21/14 12:56 AM, Daniel Murphy wrote:
> "Walter Bright"  wrote in message news:m4mua1$shh$1@digitalmars.com...
>
>> Presumably read() will throw if the size is larger than it can handle.
>> If it doesn't, this code is not buggy, but read() is.
>
> You're right, but that's really not the point.

What is your point? (Honest question.) Are you proposing that we make all array lengths signed? -- Andrei
November 21, 2014
On Friday, 21 November 2014 at 15:50:05 UTC, H. S. Teoh via Digitalmars-d wrote:
> On Fri, Nov 21, 2014 at 03:36:01PM +0000, Don via Digitalmars-d wrote:
> [...]
>> Suppose  D had a type 'natint', which could hold natural numbers in
>> the range 0..uint.max.  Sounds like 'uint', right? People make the
>> mistake of thinking that is what uint is. But it is not.
>> 
>> How would natint behave, in the type system?
>> 
>> typeof (natint - natint)  ==  int     NOT natint  !!!
>
> Wrong. (uint.max - 0) == uint.max, which is of type uint.


It is not uint.max. It is natint.max. And yes, that's an overflow condition.

Exactly the same as when you do int.max + int.max.

> If you
> interpret it as int, you get a negative number, which is wrong. So your
> proposal breaks uint in even worse ways, in that now subtracting a
> smaller number from a larger number may overflow, whereas it wouldn't
> before. So that fixes nothing, you're just shifting the problem
> somewhere else.
>
>
> T

This is not a proposal!!!! I am just illustrating the difference between what people *think* uint does, vs what it actually does.

The type that I think would be useful, would be a number in the range 0..int.max.
It has no risk of underflow.

To put it another way:

natural numbers are a subset of mathematical integers.
  (the range 0..infinity)

signed types are a subset of mathematical integers
  (the range -int.max .. int.max).

unsigned types are not a subset of mathematical integers.

They do not just have a restricted range. They have different semantics.


The question of what happens when a range is exceeded, is a different question.