disabling unary "-" for unsigned types

Steven Schveighoffer schveiguy at yahoo.com
Mon Feb 15 19:40:46 PST 2010


On Mon, 15 Feb 2010 17:21:09 -0500, Walter Bright  
<newshound1 at digitalmars.com> wrote:

> Steven Schveighoffer wrote:
>> are there any good cases besides this that Walter has?  And even if  
>> there are, we are not talking about silently mis-interpreting it.   
>> There is precedent for making valid C code an error because it is error  
>> prone.
>
>
> Here's where I'm coming from with this. The problem is that CPU integers  
> are 2's complement and a fixed number of bits. We'd like to pretend they  
> work just like whole numbers we learned about in 2nd grade arithmetic.  
> But they don't, and we can't fix it so they do. I think it's ultimately  
> fruitless to try and make them behave other than what they are: 2's  
> complement fixed arrays of bits.
>
> So, we wind up with oddities like overflow, wrap-around,  
> -int.min==int.min. Heck, we *rely* on these oddities (subtraction  
> depends on wrap-around). Sometimes, we pretend these bit values are  
> signed, sometimes unsigned, and we mix together those notions in the  
> same expression.

One further thing I'll say on this:

signed computer math makes a lot of sense to people because the limits are  
so large.  For instance, -2 billion to 2 billion.  It seems logical that a  
computer can't just keep coming up with new bits to represent numbers, but  
it seems so far off that an integer will wrap at 2 billion.  But unsigned  
math has a much more familiar boundary -- zero.  Numbers are far more  
likely to be near zero than they are near 2 billion or -2 billion.   
Applying a negation operator to an unsigned value almost *guarantees*  
wrapping past that boundary.  99% of the time, when I apply a negative  
sign to a number, I want the negative equivalent of that number.  I don't  
want some large bizarre value that has no relation to that number, despite  
what the computer thinks is sane.  I'd look at applying a negation  
operator to an unsigned int with as much scrutiny as I'd look at  
multiplying an integer by 1_000_000_000.  It's almost guaranteed to go out  
of bounds, why are you doing it?

Bringing up -int.min == int.min is exactly my point.  For integers, there  
is one value that the negation operator doesn't work as expected.  For  
unsigned integers, there is only one number that *does* work as expected  
-- zero.  All others either don't work as expected, or rely on the  
computer behaving strangely (if it is indeed expected).  To make such rare  
purposeful uses more explicit does not lower the quality of code or the  
ease of use.

-Steve



More information about the Digitalmars-d mailing list