Writing Bug-Free C/D Code

Henning Hasemann hhasemann at web.de
Mon Mar 19 03:44:54 PDT 2007


On Mon, 19 Mar 2007 19:46:50 +1100
Daniel Keep <daniel.keep.lists at gmail.com> wrote:

> It's unintuitive because you're asking the compiler to perform a
> nonsensical operation: multiplication between two partially disjoint sets.

You are right with this: Neither int nor uint are a good default type to
convert to here.
But when I compile with -w where I get a warning when putting an int
into a short, I want to somehow get warned here that the meaning of
the - sign may get reinterpreted, or better said:
That the result of this operation is implicitly casted to a type
which is not capable of representing it without loss of data
or in this case meaning (as actually no bit gets lost).

This can be very hard to track down if you have such things with variables.
Say you are mocking around with SDL and take a width of some thing
and calculating arounds with ints (width * negative value *can* be a useful
value). If your calculation is long/complex enough it'll take some time finding this.

> It's a bit like complaining that (3 * "2") doesn't work in D.  In PHP,
> it results in 6, in Python, it results in "222".  Which one's right?

Yeah right, but as you mentioned, D doesnt *allow* this instead of returning
one of the questionable results.

> > I know, changing this might break some code, but I cant help considering
> > code that relies on such implicit casting rules broken nevertheless.
> 
> This is, in my opinion, a really bad idea.  You're basically saying that
> the compiler should never complain if an operation *destroys data*.

Now. I say it should either implicitly cast so it doesnt destroy data
(ie float * int = float etc...), or complain when it has to destroy data.
In the example -2 * 3u at least meaning is changed without any complaint.
I *do not* say this should be an int.
This should be either implicicly a long (which would be capable of
representing all results from int * uint) or at least some warning
when compiling with -w.

But I must confess, after writing all the things above I tested around
a bit again and saw: Implicit conversions other than the int * uint case,
such as int * float do what I would expect.
The int * uint thing got me so screwed in the past I casted everything
manually because I feared D could do something evil ,-)


> The root problem here is that you're trying to mix signed and unsigned
> operations together, and expecting a signed result.  My personal rule of
> thumb is: never, ever get signed/unsigned types within five kilometres
> of each other.  If you think something is signed, but aren't sure,
> assert it!

I sometimes have some problems with this, as said before: Let SDL return
a width as uint and have your positions int (because they also can be negative).

I had this problems with C already. Examples of questions I have often when coding:
- "Hmm okay. You're a on-screen coordinate. You will be positive.
  But I might to want to mix you with virtual and potetially negative
  Coordinates. Also you wont be larger than 32000, as long as screens
  wont get really big. But I somehow feel I should make you an int..."
- Hm okay so I have these few things I know of they wont be negative.
  Should I make them int nevertheless? Would avoid complications and warinings,
  and the value range wouldnt be a problem.

> I actually think a better solution would be to add an Integer type to D:
> one that actually, really, truly works like an integer, and not a member
> of Z_{2^32} :P

Yeah, like the python one. Should not be too hard to implement I guess.

Henning

-- 
v4sw7Yhw4ln0pr7Ock2/3ma7uLw5Xm0l6/7DGKi2e6t6ELNSTVXb7AHIMOen5a2Xs5Mr2g5ACPR hackerkey.com



More information about the Digitalmars-d mailing list