November 21, 2014
On 11/21/14 6:03 AM, ketmar via Digitalmars-d wrote:
> On Thu, 20 Nov 2014 13:28:37 -0800
> Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
>> On 11/20/2014 7:52 AM, H. S. Teoh via Digitalmars-d wrote:
>>> What *could* be improved, is the prevention of obvious mistakes in
>>> *mixing* signed and unsigned types. Right now, D allows code like the
>>> following with no warning:
>>>
>>> 	uint x;
>>> 	int y;
>>> 	auto z = x - y;
>>>
>>> BTW, this one is the same in essence as an actual bug that I fixed in
>>> druntime earlier this year, so downplaying it as a mistake people make
>>> 'cos they confound computer math with math math is fallacious.
>>
>> What about:
>>
>>       uint x;
>>       auto z = x - 1;
>>
>> ?
>>
> here z must be `long`. and for `ulong` compiler must emit error.

Would you agree that that would break a substantial amount of correct D code? -- Andrei

November 21, 2014
On Thursday, 20 November 2014 at 20:17:15 UTC, deadalnix wrote:
> On Thursday, 20 November 2014 at 15:55:21 UTC, H. S. Teoh via
> Digitalmars-d wrote:
>> Using unsigned types for array length doesn't necessarily lead to subtle
>> bugs, if the language was stricter about mixing signed and unsigned
>> values.
>>
>
> Yes, I think that this is the real issue.

Thirded.

Array lengths are always non-negative integers.  This is axiomatic.  But the subtraction thing keeps coming up in this thread; what to do?

There's probably something fundamentally wrong with this and I'll probably be called an idiot by both "sides", but my gut feeling is that if expressions with subtraction simply returned a signed type by default, much of the problem would disappear.  It doesn't catch everything and stuff like:

uint x = 2;
uint y = 4;
uint z = x - y;

...is still going to overflow, but maybe you know what you're doing? More importantly, changing it to auto z = x - y; actually works as expected for the majority of cases.  (I'm actually on the fence re: pass/warn/error on mixing, but I _will_ note C's promotion rules have bitten me in the ass a few times and I have no particular love for them.)

-Wyatt

PS: I can't even believe how this thread has blown up, considering how it started.
November 21, 2014
On 11/21/14 6:17 AM, Ary Borenszweig wrote:
> On 11/21/14, 5:45 AM, Walter Bright wrote:
>> On 11/21/2014 12:10 AM, bearophile wrote:
>>> Walter Bright:
>>>
>>>> All you're doing is trading 0 crossing for 0x7FFFFFFF crossing
>>>> issues, and
>>>> pretending the problems have gone away.
>>>
>>> I'm not pretending anything. I am asking in practical programming what
>>> of the
>>> two solutions leads to leas problems/bugs. So far I've seen the unsigned
>>> solution and I've seen it's highly bug-prone.
>>
>> I'm suggesting that having a bug and detecting the bug are two different
>> things. The 0-crossing bug is easier to detect, but that doesn't mean
>> that shifting the problem to 0x7FFFFFFF crossing bugs is making the bug
>> count less.
>>
>>
>>>> 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.
>>>
>>> Is this true? Do you have some examples of buggy code?
>>
>> http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html
>>
>>
>
> "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?

Every time you read a DVD image :o). I should say that in my doctoral work it was often the case I'd have very large arrays.

Andrei

November 21, 2014
On Thursday, 20 November 2014 at 08:14:41 UTC, Walter Bright wrote:
clip
>
> For example, in America we drive on the right. In Australia, they drive on the left. When I visit Australia, I know this, but when stepping out into the road I instinctively check my left for cars, step into the road, and my foot gets run over by a car coming from the right. I've had to be very careful as a pedestrian there, as my intuition would get me killed.
>
> Don't mess with systems programmers' intuitions. It'll cause more problems than it solves.

I live in Quebec and my intuition always tells me to look both ways - because you never know :o)

November 21, 2014
On Fri, 21 Nov 2014 08:31:13 -0800
Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com>
wrote:

> Would you agree that that would break a substantial amount of correct D code? -- Andrei
i don't think that code with possible int wrapping and `auto` is correct, so the answer is "no". bad code must be made bad.


November 21, 2014
On Friday, 21 November 2014 at 16:48:35 UTC, CraigDillabaugh wrote:
> I live in Quebec and my intuition always tells me to look both ways - because you never know :o)

While doing my driver's training years ago, my instructor half-jokingly warned us never to jaywalk in Quebec unless we have a death wish and want to hear all about chalices and tabernacles.
November 21, 2014
Am Wed, 19 Nov 2014 10:22:49 +0000
schrieb "Dominikus Dittes Scherkl"
<Dominikus.Scherkl@continental-corporation.com>:

> On Wednesday, 19 November 2014 at 09:06:16 UTC, Maroc Leise wrote:
> > Clearly size_t (which I tend to alias with ℕ in my code for
> > brevity and coolness)
> No, this is far from the implied infinite set.
> A much better candidate for ℕ is BigUInt (and ℤ for BigInt)

How far exactly is it from infinity? And how much closer is BigInt? I wanted a fast ℕ within the constraints of the machine. ;)

-- 
Marco

November 21, 2014
On Fri, Nov 21, 2014 at 08:31:13AM -0800, Andrei Alexandrescu via Digitalmars-d wrote:
> On 11/21/14 6:03 AM, ketmar via Digitalmars-d wrote:
> >On Thu, 20 Nov 2014 13:28:37 -0800
> >Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >
> >>On 11/20/2014 7:52 AM, H. S. Teoh via Digitalmars-d wrote:
> >>>What *could* be improved, is the prevention of obvious mistakes in *mixing* signed and unsigned types. Right now, D allows code like the following with no warning:
> >>>
> >>>	uint x;
> >>>	int y;
> >>>	auto z = x - y;
> >>>
> >>>BTW, this one is the same in essence as an actual bug that I fixed in druntime earlier this year, so downplaying it as a mistake people make 'cos they confound computer math with math math is fallacious.
> >>
> >>What about:
> >>
> >>      uint x;
> >>      auto z = x - 1;
> >>
> >>?
> >>
> >here z must be `long`. and for `ulong` compiler must emit error.

What if x==uint.max?


> Would you agree that that would break a substantial amount of correct D code? -- Andrei

Yeah I don't think it's a good idea for subtraction to yield a different type from its operands. Non-closure of operators (i.e., results are of a different type than operands) leads to a lot of frustration because you keep ending up with the wrong type, and inevitably people will just throw in random casts everywhere just to make things work.


T

-- 
We are in class, we are supposed to be learning, we have a teacher... Is it too much that I expect him to teach me??? -- RL
November 21, 2014
Am Thu, 20 Nov 2014 08:18:23 +0000
schrieb "Don" <x@nospam.com>:

> It's particularly challenging in D because of the widespread use of 'auto':
> 
> auto x = foo();
> auto y = bar();
> auto z = baz();
> 
> if (x - y > z) { ... }
> 
> 
> This might be a bug, if one of these functions returns an unsigned type.  Good luck finding that. Note that if all functions return unsigned, there isn't even any signed-unsigned mismatch.

With those function names I cannot write code.

ℕ x = length();
ℕ y = index();
ℕ z = requiredRange();

if (x - y > z) { ... }

Ah, now we're getting somewhere. Yes the code is obviously correct. You need to be aware of the value ranges of your variables and write subtractions in a way that the result can only be >= 0. If you realize that you cannot guarantee that for some case, you just found a logic bug. An invalid program state that you need to assert/if-else/throw.

I don't get why so many APIs return ints. Must be to support Java or something where proper unsigned types aren't available.

-- 
Marco

November 21, 2014
On 11/21/14, 11:29 AM, ketmar via Digitalmars-d wrote:
> On Fri, 21 Nov 2014 19:31:23 +1100
> Daniel Murphy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
>> "bearophile"  wrote in message news:lkcltlokangpzzdzzfjg@forum.dlang.org...
>>
>>>  From my experience in coding in D they are far more unlikely than
>>> sign-related bugs of array lengths.
>>
>> Here's a simple program to calculate the relative size of two files, that
>> will not work correctly with unsigned lengths.
>>
>> module sizediff
>>
>> import std.file;
>> import std.stdio;
>>
>> void main(string[] args)
>> {
>>      assert(args.length == 3, "Usage: sizediff file1 file2");
>>      auto l1 = args[1].read().length;
>>      auto l2 = args[2].read().length;
>>      writeln("Difference: ", l1 - l2);
>> }
>>
>> The two ways this can fail (that I want to highlight) are:
>> 1. If either file is too large to fit in a size_t the result will (probably)
>> be wrong
>> 2. If file2 is bigger than file1 the result will be wrong
>>
>> If length was signed, problem 2 would not exist, and problem 1 would be more
>> likely to occur.  I think it's clear that signed lengths would work for more
>> possible realistic inputs.
> no, the problem 2 just becomes hidden. while the given code works most
> of the time, it is still broken.

So how would you solve problem 2?