disabling unary "-" for unsigned types

Steven Schveighoffer schveiguy at yahoo.com
Tue Feb 16 04:28:56 PST 2010


On Tue, 16 Feb 2010 00:35:21 -0500, Ellery Newcomer  
<ellery-newcomer at utulsa.edu> wrote:

> On 02/15/2010 09:17 PM, Steven Schveighoffer wrote:
>> On Mon, 15 Feb 2010 21:32:21 -0500, Rainer Deyke <rainerd at eldwood.com>
>> wrote:
>>
>>> Ellery Newcomer wrote:
>>>> On 02/15/2010 05:33 PM, Steven Schveighoffer wrote:
>>>>> uint a = -1; // error
>>>>
>>>> I can't say I would appreciate having to write
>>>>
>>>> uint a = 0xFFFFFFFF;
>>>>
>>>> or the equivalent for ulong.
>>>
>>> uint a = ~0u;
>>
>> even ~0 works, no need for the u (although it makes things clearer).
>>
>> Ellery, you didn't read my original post thoroughly, I said this was the
>> most common case of wanting to use unary negative on an unsigned value,
>> and it's easily rewritten, with the same number of characters no less.
>>
>> -Steve
>
> Ohhh! that post! You're right; I missed that part.
>
> Alright, here's something I found myself writing just today or yesterday:
>
> //x,r are long, n is ulong
>
> if(x < 0){
>    ulong ux = -x;
>    ...
> }

I think at the same time you can assign an int to a uint without issue,  
assigning an int that is the result of a negation operator on a uint to  
another uint is a problem.  This means that the type of the expression:

-n

where n is unsigned can't simply be the signed version of n's type.  If it  
was, it would be impossible to tell the difference between assigning a  
negation of an unsigned value from a simple int result (which has a 50%  
chance of being positive).  I don't know how the internal workings of the  
compiler behave, but there has to be a way to single the bad case out.  We  
already have range propagation, this could simply be part of it.

>
> I also have
>
> if(r < 0){
>    return n - (-r) % n;
> }

This is fine, you are not assigning the negation of unsigned to an  
unsigned value.  Binary subtraction on unsigned and signed numbers is not  
as error prone.

>
> emphasis on ensuring dividend is positive before it gets promoted to  
> ulong, etc etc, and I do guard that r is not remotely close to  
> ulong.max/min.
>
> assuming that the return type is long (it isn't, but it might as well  
> be, since n is always within [2,long.max]) or gets assigned to long or  
> whatever.
>
> -The bottom one obeys your rules.
> -The top one doesn't.

The top is a good example.  It is not something I thought of, but I think  
in the end, it should be allowed.  Coming up with all the nuances of the  
behavior is key to finding a sound rule to try and implement, and how to  
explain its behavior through example.

-Steve



More information about the Digitalmars-d mailing list