Mixing operations with signed and unsigned types

Stewart Gordon smjg_1998 at yahoo.com
Mon Jul 5 05:59:39 PDT 2010


bearophile wrote:
> Stewart Gordon:
<snip>
>> Some of us prefer to use unsigned types where the value is 
>> semantically unsigned, and know what we're doing. So any measures 
>> to stronghold programmers against using them are going to be a 
>> nuisance.
> 
> I have not asked to remove the unsigned types, so you can relax. And 
> replacing lengths/indexes with signed values isn't a way to forbid 
> you to use unsigned values in your programs, it's right the opposite: 
> it's a way to not force me (and many other programmers that want to 
> write simple D non-system programs) to use unsigned values in my 
> code.

I didn't think you were asking for unsigned types to be removed.  My 
point was that having language features and APIs relying on signed types 
for semantically unsigned values is not just a way of not forcing you to 
use unsigned types - it's also potentially a way of forcing you not to 
use them, or to pepper your code with casts if you do.  I guess you just 
can't please everybody.

<snip>
>> I can also imagine promoting your mindset leading to edit wars 
>> between developers declaring an int and then putting
>>      assert (qwert >= 0);
>> in the class invariant, and those who see this and think it's 
>> brain-damaged.
> 
> This is quite interesting. You think that using an unsigned type in D 
> is today the same thing than using a signed value + an assert of it 
> not being negative?

Not quite - an unsigned type has twice the range.  It's true that this 
extra range isn't always used, but in some apps/APIs there may be bits 
that use the extra range and bits that don't, and it is often simpler to 
use unsigned everywhere it's logical than to expect the user to remember 
which is which.

> In the beginning, when I was used to Delphi programming I have done 
> the same, but I have soon found out that was unsafe. Today D unsigned 
> values don't give you a nice overflow error (as I have asked Walter 
> many times) when you try to assign them a number outside their range, 
> they happily wrap around, this causes bugs in programs.

Trouble is that it would add a lot of code to every integer arithmetic 
operation.  Of course, it could be omitted in release builds, but 
arithmetic is so frequent an activity that the extent it would slow down 
and bloat development builds would be annoying.

> So using an unsigned number to denote a value that can't be negative 
> is dangerous and it can be stupid too. In D you need to take a signed 
> value from outside and then assign it to a unsigned value only after 
> you have tested it to be nonnegative.

Why can't I read a 32-bit unsigned integer from a binary file, or use 
such functions as std.conv.toUint (whereby '-' is just another illegal 
character)?

>> But it is all the more reason to fix unsigned op signed to be 
>> signed, if it is to be allowed at all.  The way it is at the 
>> moment, a single unsigned value in a formula can force the whole 
>> result to be unsigned, thereby leading to unexpected results.
> 
> I think Walter will not change this, because this way D syntax equal 
> to C syntax does things different from C

But D isn't designed to be fully source-compatible with C, hence the 
suggestion of making it illegal.

> (there are few exceptions to this D rule, like fixed-sized arrays are 
> passed by value in D and by pointer in C).
<snip>

Indeed, the "looks like C, acts like C" principle isn't consistently 
applied.  For instance, in switch, we have:
- a case (no pun intended) of it being applied, even though there's no 
real reason for D to allow the code (fall through)
- a case of it being breached (SwitchDefault error).

Stewart.


More information about the Digitalmars-d-learn mailing list