Jump to page: 1 2
Thread overview
[phobos] [Fwd: "Unsigned-related bugs never occur in real code."]
Jan 21, 2010
Sean Kelly
Jan 21, 2010
Don Clugston
Jan 21, 2010
Sean Kelly
Jan 21, 2010
Don Clugston
Jan 21, 2010
Sean Kelly
Jan 21, 2010
Sean Kelly
January 20, 2010
Is there anything we can do about this?

Andrei

-------- Original Message --------
Subject: "Unsigned-related bugs never occur in real code."
Date: Wed, 20 Jan 2010 20:42:50 -0800
From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
Organization: Digital Mars
Newsgroups: digitalmars.D

"It's an academic problem. Don't worry about it and move on."

That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:

import std.math, std.stdio;

void main() {
     auto a = [ 4, 4, 2, 3, 2 ];
     float avgdist = 0;
     uint count;

     foreach (i, e1; a) {
         foreach (j, e2; a) {
             if (i == j) continue;
             if (e1 != e2) continue;
             ++count;
             avgdist += abs(i - j);
         }
     }

     writeln(count, " ", avgdist / count);
}

May this post be an innocent victim of the war against unsigned-related bugs.


Andrei
January 20, 2010
My first inclination would be for abs to only accept signed values.  Unsigned values don't really seem appropriate for unchecked math operations.

On Jan 20, 2010, at 8:50 PM, Andrei Alexandrescu wrote:

> Is there anything we can do about this?
> 
> Andrei
> 
> -------- Original Message --------
> Subject: "Unsigned-related bugs never occur in real code."
> Date: Wed, 20 Jan 2010 20:42:50 -0800
> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
> Organization: Digital Mars
> Newsgroups: digitalmars.D
> 
> "It's an academic problem. Don't worry about it and move on."
> 
> That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:
> 
> import std.math, std.stdio;
> 
> void main() {
>    auto a = [ 4, 4, 2, 3, 2 ];
>    float avgdist = 0;
>    uint count;
> 
>    foreach (i, e1; a) {
>        foreach (j, e2; a) {
>            if (i == j) continue;
>            if (e1 != e2) continue;
>            ++count;
>            avgdist += abs(i - j);
>        }
>    }
> 
>    writeln(count, " ", avgdist / count);
> }
> 
> May this post be an innocent victim of the war against unsigned-related bugs.
> 
> 
> Andrei
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos

January 21, 2010
2010/1/21 Sean Kelly <sean at invisibleduck.org>:
> My first inclination would be for abs to only accept signed values. ?Unsigned values don't really seem appropriate for unchecked math operations.

I agree, it doesn't make sense to take the absolute value of something which doesn't have a sign. With range checking, it ought to be possible to implicitly cast from uint to int, which would allow all of the sensible uses. Unfortunately, implicit casting and templates don't interact well. So I think abs() might need to go back to being a non-template function.

> On Jan 20, 2010, at 8:50 PM, Andrei Alexandrescu wrote:
>
>> Is there anything we can do about this?
>>
>> Andrei
>>
>> -------- Original Message --------
>> Subject: "Unsigned-related bugs never occur in real code."
>> Date: Wed, 20 Jan 2010 20:42:50 -0800
>> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
>> Organization: Digital Mars
>> Newsgroups: digitalmars.D
>>
>> "It's an academic problem. Don't worry about it and move on."
>>
>> That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:
>>
>> import std.math, std.stdio;
>>
>> void main() {
>> ? ?auto a = [ 4, 4, 2, 3, 2 ];
>> ? ?float avgdist = 0;
>> ? ?uint count;
>>
>> ? ?foreach (i, e1; a) {
>> ? ? ? ?foreach (j, e2; a) {
>> ? ? ? ? ? ?if (i == j) continue;
>> ? ? ? ? ? ?if (e1 != e2) continue;
>> ? ? ? ? ? ?++count;
>> ? ? ? ? ? ?avgdist += abs(i - j);
>> ? ? ? ?}
>> ? ?}
>>
>> ? ?writeln(count, " ", avgdist / count);
>> }
>>
>> May this post be an innocent victim of the war against unsigned-related bugs.
>>
>>
>> Andrei
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
January 21, 2010
The problem persists even if I remove the call to abs(). At least its removal makes things look more suspicious.

Andrei

Don Clugston wrote:
> 2010/1/21 Sean Kelly <sean at invisibleduck.org>:
>> My first inclination would be for abs to only accept signed values.  Unsigned values don't really seem appropriate for unchecked math operations.
> 
> I agree, it doesn't make sense to take the absolute value of something which doesn't have a sign. With range checking, it ought to be possible to implicitly cast from uint to int, which would allow all of the sensible uses. Unfortunately, implicit casting and templates don't interact well. So I think abs() might need to go back to being a non-template function.
> 
>> On Jan 20, 2010, at 8:50 PM, Andrei Alexandrescu wrote:
>>
>>> Is there anything we can do about this?
>>>
>>> Andrei
>>>
>>> -------- Original Message --------
>>> Subject: "Unsigned-related bugs never occur in real code."
>>> Date: Wed, 20 Jan 2010 20:42:50 -0800
>>> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
>>> Organization: Digital Mars
>>> Newsgroups: digitalmars.D
>>>
>>> "It's an academic problem. Don't worry about it and move on."
>>>
>>> That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:
>>>
>>> import std.math, std.stdio;
>>>
>>> void main() {
>>>    auto a = [ 4, 4, 2, 3, 2 ];
>>>    float avgdist = 0;
>>>    uint count;
>>>
>>>    foreach (i, e1; a) {
>>>        foreach (j, e2; a) {
>>>            if (i == j) continue;
>>>            if (e1 != e2) continue;
>>>            ++count;
>>>            avgdist += abs(i - j);
>>>        }
>>>    }
>>>
>>>    writeln(count, " ", avgdist / count);
>>> }
>>>
>>> May this post be an innocent victim of the war against unsigned-related bugs.
>>>
>>>
>>> Andrei
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
January 21, 2010
I got a reasonable answer by casting to int before calling abs():

import std.math, std.stdio;

void main() {
   auto a = [ 4, 4, 2, 3, 2 ];
   float avgdist = 0;
   uint count;

   foreach (i, e1; a) {
       foreach (j, e2; a) {
           if (i == j) continue;
           if (e1 != e2) continue;
           ++count;
           writeln("adding ", cast(int)(i - j));
           avgdist += abs(cast(int)(i - j));
       }
   }

   writeln(count, " ", avgdist / count);
}

On Jan 21, 2010, at 12:41 AM, Andrei Alexandrescu wrote:

> The problem persists even if I remove the call to abs(). At least its removal makes things look more suspicious.
> 
> Andrei
> 
> Don Clugston wrote:
>> 2010/1/21 Sean Kelly <sean at invisibleduck.org>:
>>> My first inclination would be for abs to only accept signed values.  Unsigned values don't really seem appropriate for unchecked math operations.
>> I agree, it doesn't make sense to take the absolute value of something which doesn't have a sign. With range checking, it ought to be possible to implicitly cast from uint to int, which would allow all of the sensible uses. Unfortunately, implicit casting and templates don't interact well. So I think abs() might need to go back to being a non-template function.
>>> On Jan 20, 2010, at 8:50 PM, Andrei Alexandrescu wrote:
>>> 
>>>> Is there anything we can do about this?
>>>> 
>>>> Andrei
>>>> 
>>>> -------- Original Message --------
>>>> Subject: "Unsigned-related bugs never occur in real code."
>>>> Date: Wed, 20 Jan 2010 20:42:50 -0800
>>>> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
>>>> Organization: Digital Mars
>>>> Newsgroups: digitalmars.D
>>>> 
>>>> "It's an academic problem. Don't worry about it and move on."
>>>> 
>>>> That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:
>>>> 
>>>> import std.math, std.stdio;
>>>> 
>>>> void main() {
>>>>   auto a = [ 4, 4, 2, 3, 2 ];
>>>>   float avgdist = 0;
>>>>   uint count;
>>>> 
>>>>   foreach (i, e1; a) {
>>>>       foreach (j, e2; a) {
>>>>           if (i == j) continue;
>>>>           if (e1 != e2) continue;
>>>>           ++count;
>>>>           avgdist += abs(i - j);
>>>>       }
>>>>   }
>>>> 
>>>>   writeln(count, " ", avgdist / count);
>>>> }
>>>> 
>>>> May this post be an innocent victim of the war against unsigned-related bugs.
>>>> 
>>>> 
>>>> Andrei
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>> 
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos

January 21, 2010
Fixed version:

import std.math, std.stdio;

void main() {
    auto a = [ 4, 4, 2, 3, 2 ];
    float avgdist = 0;
    uint count;

    foreach (i, e1; a[0 .. $-1]) {
        foreach (j, e2; a[i+1 .. $]) {
            if (e1 != e2) continue;
            count++;
            avgdist += j+1;
        }
    }

    writeln(count, " ", avgdist / count);
}

:)  I'm sure that's not what you were asking though...

-Steve



----- Original Message ----
> From: Andrei Alexandrescu <andrei at erdani.com>
> To: Discuss the phobos library for D <phobos at puremagic.com>
> Sent: Wed, January 20, 2010 11:50:20 PM
> Subject: [phobos] [Fwd: "Unsigned-related bugs never occur in real code."]
> 
> Is there anything we can do about this?
> 
> Andrei
> 
> -------- Original Message --------
> Subject: "Unsigned-related bugs never occur in real code."
> Date: Wed, 20 Jan 2010 20:42:50 -0800
> From: Andrei Alexandrescu
> Organization: Digital Mars
> Newsgroups: digitalmars.D
> 
> "It's an academic problem. Don't worry about it and move on."
> 
> That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:
> 
> import std.math, std.stdio;
> 
> void main() {
>     auto a = [ 4, 4, 2, 3, 2 ];
>     float avgdist = 0;
>     uint count;
> 
>     foreach (i, e1; a) {
>         foreach (j, e2; a) {
>             if (i == j) continue;
>             if (e1 != e2) continue;
>             ++count;
>             avgdist += abs(i - j);
>         }
>     }
> 
>     writeln(count, " ", avgdist / count);
> }
> 
> May this post be an innocent victim of the war against unsigned-related bugs.
> 
> 
> Andrei
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos




January 21, 2010
The problem is that this code passes:

void main()
{
   float x = 0;
   x += 2u - 5u;
   assert(x == uint.max - 3);
}
But it's pretty unexpected and unhelpful behaviour.
It *doesn't* pass if you set:   x = x + 2u - 5u. But x += y is
equivalent to:   x = x + cast(typeof(x))y;  and since there's an
explicit cast, no error message is generated.



2010/1/21 Sean Kelly <sean at invisibleduck.org>:
> I got a reasonable answer by casting to int before calling abs():
>
> import std.math, std.stdio;
>
> void main() {
> ? auto a = [ 4, 4, 2, 3, 2 ];
> ? float avgdist = 0;
> ? uint count;
>
> ? foreach (i, e1; a) {
> ? ? ? foreach (j, e2; a) {
> ? ? ? ? ? if (i == j) continue;
> ? ? ? ? ? if (e1 != e2) continue;
> ? ? ? ? ? ++count;
> ? ? ? ? ? writeln("adding ", cast(int)(i - j));
> ? ? ? ? ? avgdist += abs(cast(int)(i - j));
> ? ? ? }
> ? }
>
> ? writeln(count, " ", avgdist / count);
> }
>
> On Jan 21, 2010, at 12:41 AM, Andrei Alexandrescu wrote:
>
>> The problem persists even if I remove the call to abs(). At least its removal makes things look more suspicious.
>>
>> Andrei
>>
>> Don Clugston wrote:
>>> 2010/1/21 Sean Kelly <sean at invisibleduck.org>:
>>>> My first inclination would be for abs to only accept signed values. ?Unsigned values don't really seem appropriate for unchecked math operations.
>>> I agree, it doesn't make sense to take the absolute value of something which doesn't have a sign. With range checking, it ought to be possible to implicitly cast from uint to int, which would allow all of the sensible uses. Unfortunately, implicit casting and templates don't interact well. So I think abs() might need to go back to being a non-template function.
>>>> On Jan 20, 2010, at 8:50 PM, Andrei Alexandrescu wrote:
>>>>
>>>>> Is there anything we can do about this?
>>>>>
>>>>> Andrei
>>>>>
>>>>> -------- Original Message --------
>>>>> Subject: "Unsigned-related bugs never occur in real code."
>>>>> Date: Wed, 20 Jan 2010 20:42:50 -0800
>>>>> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
>>>>> Organization: Digital Mars
>>>>> Newsgroups: digitalmars.D
>>>>>
>>>>> "It's an academic problem. Don't worry about it and move on."
>>>>>
>>>>> That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:
>>>>>
>>>>> import std.math, std.stdio;
>>>>>
>>>>> void main() {
>>>>> ? auto a = [ 4, 4, 2, 3, 2 ];
>>>>> ? float avgdist = 0;
>>>>> ? uint count;
>>>>>
>>>>> ? foreach (i, e1; a) {
>>>>> ? ? ? foreach (j, e2; a) {
>>>>> ? ? ? ? ? if (i == j) continue;
>>>>> ? ? ? ? ? if (e1 != e2) continue;
>>>>> ? ? ? ? ? ++count;
>>>>> ? ? ? ? ? avgdist += abs(i - j);
>>>>> ? ? ? }
>>>>> ? }
>>>>>
>>>>> ? writeln(count, " ", avgdist / count);
>>>>> }
>>>>>
>>>>> May this post be an innocent victim of the war against unsigned-related bugs.
>>>>>
>>>>>
>>>>> Andrei
>>>>> _______________________________________________
>>>>> phobos mailing list
>>>>> phobos at puremagic.com
>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
January 21, 2010
On a 64-bit system you have a portability problem. Generally casts are bad because they specify the target type when you actually want a different manipulation (in this case, changing signedness).

std.traits has a function called "unsigned" that takes an integral of any length and returns the corresponding unsigned integral. I'll define also "signed". With that and with the change to abs(), abs(j - i) is an error (static assert), and will actually suggest that you use abs(signed(j - i)) in its error message.

At any rate, all these fixes don't make me feel much better. Bugs are easy to come by and difficult to find (my initial code involved an associative array, and AAs have their _own_ bugs that made me suspicious).

In brief, D still has big problems with handling signed and unsigned integrals.


Andrei

Sean Kelly wrote:
> I got a reasonable answer by casting to int before calling abs():
> 
> import std.math, std.stdio;
> 
> void main() {
>    auto a = [ 4, 4, 2, 3, 2 ];
>    float avgdist = 0;
>    uint count;
> 
>    foreach (i, e1; a) {
>        foreach (j, e2; a) {
>            if (i == j) continue;
>            if (e1 != e2) continue;
>            ++count;
>            writeln("adding ", cast(int)(i - j));
>            avgdist += abs(cast(int)(i - j));
>        }
>    }
> 
>    writeln(count, " ", avgdist / count);
> }
> 
> On Jan 21, 2010, at 12:41 AM, Andrei Alexandrescu wrote:
> 
>> The problem persists even if I remove the call to abs(). At least its removal makes things look more suspicious.
>>
>> Andrei
>>
>> Don Clugston wrote:
>>> 2010/1/21 Sean Kelly <sean at invisibleduck.org>:
>>>> My first inclination would be for abs to only accept signed values.  Unsigned values don't really seem appropriate for unchecked math operations.
>>> I agree, it doesn't make sense to take the absolute value of something which doesn't have a sign. With range checking, it ought to be possible to implicitly cast from uint to int, which would allow all of the sensible uses. Unfortunately, implicit casting and templates don't interact well. So I think abs() might need to go back to being a non-template function.
>>>> On Jan 20, 2010, at 8:50 PM, Andrei Alexandrescu wrote:
>>>>
>>>>> Is there anything we can do about this?
>>>>>
>>>>> Andrei
>>>>>
>>>>> -------- Original Message --------
>>>>> Subject: "Unsigned-related bugs never occur in real code."
>>>>> Date: Wed, 20 Jan 2010 20:42:50 -0800
>>>>> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
>>>>> Organization: Digital Mars
>>>>> Newsgroups: digitalmars.D
>>>>>
>>>>> "It's an academic problem. Don't worry about it and move on."
>>>>>
>>>>> That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:
>>>>>
>>>>> import std.math, std.stdio;
>>>>>
>>>>> void main() {
>>>>>   auto a = [ 4, 4, 2, 3, 2 ];
>>>>>   float avgdist = 0;
>>>>>   uint count;
>>>>>
>>>>>   foreach (i, e1; a) {
>>>>>       foreach (j, e2; a) {
>>>>>           if (i == j) continue;
>>>>>           if (e1 != e2) continue;
>>>>>           ++count;
>>>>>           avgdist += abs(i - j);
>>>>>       }
>>>>>   }
>>>>>
>>>>>   writeln(count, " ", avgdist / count);
>>>>> }
>>>>>
>>>>> May this post be an innocent victim of the war against unsigned-related bugs.
>>>>>
>>>>>
>>>>> Andrei
>>>>> _______________________________________________
>>>>> phobos mailing list
>>>>> phobos at puremagic.com
>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
> 
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
January 21, 2010
Don, do you have an idea of a simple change to the language that would prevent at least the most pernicious of these issues?

Andrei

Don Clugston wrote:
> The problem is that this code passes:
> 
> void main()
> {
>    float x = 0;
>    x += 2u - 5u;
>    assert(x == uint.max - 3);
> }
> But it's pretty unexpected and unhelpful behaviour.
> It *doesn't* pass if you set:   x = x + 2u - 5u. But x += y is
> equivalent to:   x = x + cast(typeof(x))y;  and since there's an
> explicit cast, no error message is generated.
> 
> 
> 
> 2010/1/21 Sean Kelly <sean at invisibleduck.org>:
>> I got a reasonable answer by casting to int before calling abs():
>>
>> import std.math, std.stdio;
>>
>> void main() {
>>   auto a = [ 4, 4, 2, 3, 2 ];
>>   float avgdist = 0;
>>   uint count;
>>
>>   foreach (i, e1; a) {
>>       foreach (j, e2; a) {
>>           if (i == j) continue;
>>           if (e1 != e2) continue;
>>           ++count;
>>           writeln("adding ", cast(int)(i - j));
>>           avgdist += abs(cast(int)(i - j));
>>       }
>>   }
>>
>>   writeln(count, " ", avgdist / count);
>> }
>>
>> On Jan 21, 2010, at 12:41 AM, Andrei Alexandrescu wrote:
>>
>>> The problem persists even if I remove the call to abs(). At least its removal makes things look more suspicious.
>>>
>>> Andrei
>>>
>>> Don Clugston wrote:
>>>> 2010/1/21 Sean Kelly <sean at invisibleduck.org>:
>>>>> My first inclination would be for abs to only accept signed values.  Unsigned values don't really seem appropriate for unchecked math operations.
>>>> I agree, it doesn't make sense to take the absolute value of something which doesn't have a sign. With range checking, it ought to be possible to implicitly cast from uint to int, which would allow all of the sensible uses. Unfortunately, implicit casting and templates don't interact well. So I think abs() might need to go back to being a non-template function.
>>>>> On Jan 20, 2010, at 8:50 PM, Andrei Alexandrescu wrote:
>>>>>
>>>>>> Is there anything we can do about this?
>>>>>>
>>>>>> Andrei
>>>>>>
>>>>>> -------- Original Message --------
>>>>>> Subject: "Unsigned-related bugs never occur in real code."
>>>>>> Date: Wed, 20 Jan 2010 20:42:50 -0800
>>>>>> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
>>>>>> Organization: Digital Mars
>>>>>> Newsgroups: digitalmars.D
>>>>>>
>>>>>> "It's an academic problem. Don't worry about it and move on."
>>>>>>
>>>>>> That's what Walter kept on telling me. Yet I've spent the better part of an hour reducing a bug down to the following:
>>>>>>
>>>>>> import std.math, std.stdio;
>>>>>>
>>>>>> void main() {
>>>>>>   auto a = [ 4, 4, 2, 3, 2 ];
>>>>>>   float avgdist = 0;
>>>>>>   uint count;
>>>>>>
>>>>>>   foreach (i, e1; a) {
>>>>>>       foreach (j, e2; a) {
>>>>>>           if (i == j) continue;
>>>>>>           if (e1 != e2) continue;
>>>>>>           ++count;
>>>>>>           avgdist += abs(i - j);
>>>>>>       }
>>>>>>   }
>>>>>>
>>>>>>   writeln(count, " ", avgdist / count);
>>>>>> }
>>>>>>
>>>>>> May this post be an innocent victim of the war against unsigned-related bugs.
>>>>>>
>>>>>>
>>>>>> Andrei
>>>>>> _______________________________________________
>>>>>> phobos mailing list
>>>>>> phobos at puremagic.com
>>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>> _______________________________________________
>>>>> phobos mailing list
>>>>> phobos at puremagic.com
>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>>
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
January 21, 2010
Yeah, I was mostly responding to your earlier comment that casting didn't work for you. If you really wanted to cast it would be to ptrdiff_t anyway.

I agree that there's a more fundamental problem though. Weren't we going to make implicit narrowing conversions an error?  I know it isn't in the spirit of c, but c allows all sorts of horrible nonsense.

Sent from my iPhone

On Jan 21, 2010, at 8:22 AM, Andrei Alexandrescu <andrei at erdani.com> wrote:

> On a 64-bit system you have a portability problem. Generally casts are bad because they specify the target type when you actually want a different manipulation (in this case, changing signedness).
>
> std.traits has a function called "unsigned" that takes an integral of any length and returns the corresponding unsigned integral. I'll define also "signed". With that and with the change to abs(), abs(j - i) is an error (static assert), and will actually suggest that you use abs(signed(j - i)) in its error message.
>
> At any rate, all these fixes don't make me feel much better. Bugs are easy to come by and difficult to find (my initial code involved an associative array, and AAs have their _own_ bugs that made me suspicious).
>
> In brief, D still has big problems with handling signed and unsigned integrals.
>
>
> Andrei
>
> Sean Kelly wrote:
>> I got a reasonable answer by casting to int before calling abs():
>> import std.math, std.stdio;
>> void main() {
>>   auto a = [ 4, 4, 2, 3, 2 ];
>>   float avgdist = 0;
>>   uint count;
>>   foreach (i, e1; a) {
>>       foreach (j, e2; a) {
>>           if (i == j) continue;
>>           if (e1 != e2) continue;
>>           ++count;
>>           writeln("adding ", cast(int)(i - j));
>>           avgdist += abs(cast(int)(i - j));
>>       }
>>   }
>>   writeln(count, " ", avgdist / count);
>> }
>> On Jan 21, 2010, at 12:41 AM, Andrei Alexandrescu wrote:
>>> The problem persists even if I remove the call to abs(). At least its removal makes things look more suspicious.
>>>
>>> Andrei
>>>
>>> Don Clugston wrote:
>>>> 2010/1/21 Sean Kelly <sean at invisibleduck.org>:
>>>>> My first inclination would be for abs to only accept signed values.  Unsigned values don't really seem appropriate for unchecked math operations.
>>>> I agree, it doesn't make sense to take the absolute value of
>>>> something
>>>> which doesn't have a sign. With range checking, it ought to be
>>>> possible to implicitly cast from uint to int, which would allow
>>>> all of
>>>> the sensible uses. Unfortunately, implicit casting and templates
>>>> don't
>>>> interact well. So I think abs() might need to go back to being a
>>>> non-template function.
>>>>> On Jan 20, 2010, at 8:50 PM, Andrei Alexandrescu wrote:
>>>>>
>>>>>> Is there anything we can do about this?
>>>>>>
>>>>>> Andrei
>>>>>>
>>>>>> -------- Original Message --------
>>>>>> Subject: "Unsigned-related bugs never occur in real code."
>>>>>> Date: Wed, 20 Jan 2010 20:42:50 -0800
>>>>>> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
>>>>>> Organization: Digital Mars
>>>>>> Newsgroups: digitalmars.D
>>>>>>
>>>>>> "It's an academic problem. Don't worry about it and move on."
>>>>>>
>>>>>> That's what Walter kept on telling me. Yet I've spent the
>>>>>> better part of
>>>>>> an hour reducing a bug down to the following:
>>>>>>
>>>>>> import std.math, std.stdio;
>>>>>>
>>>>>> void main() {
>>>>>>  auto a = [ 4, 4, 2, 3, 2 ];
>>>>>>  float avgdist = 0;
>>>>>>  uint count;
>>>>>>
>>>>>>  foreach (i, e1; a) {
>>>>>>      foreach (j, e2; a) {
>>>>>>          if (i == j) continue;
>>>>>>          if (e1 != e2) continue;
>>>>>>          ++count;
>>>>>>          avgdist += abs(i - j);
>>>>>>      }
>>>>>>  }
>>>>>>
>>>>>>  writeln(count, " ", avgdist / count);
>>>>>> }
>>>>>>
>>>>>> May this post be an innocent victim of the war against unsigned-
>>>>>> related
>>>>>> bugs.
>>>>>>
>>>>>>
>>>>>> Andrei
>>>>>> _______________________________________________
>>>>>> phobos mailing list
>>>>>> phobos at puremagic.com
>>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>> _______________________________________________
>>>>> phobos mailing list
>>>>> phobos at puremagic.com
>>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>>
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
« First   ‹ Prev
1 2