Implicit type conversions with data loss

Jonathan M Davis jmdavisProg at gmx.com
Tue Jun 5 23:18:29 PDT 2012


On Wednesday, June 06, 2012 10:07:04 Dmitry Olshansky wrote:
> On 05.06.2012 22:06, ctrl wrote:
> > I don't want them to be performed at all. How do I disable this 'feature'?
> > 
> > For example, take a look at this code:
> > 
> > import std.stdio;
> > void main() {
> > int x = -1;
> > uint b = x;
> > writeln(b);
> > }
> > 
> > It outputs 4294967295, but I want a compile-time error instead. Any
> > suggestions?
> > (compiler version dmd 2.059)
> 
> There is no information lost. Try casting it back to int.

int <-> uint is a narrowing conversion in _both_ directions, and doesn't lose 
data in _either_ direction, which I find rather funny.

In any case, if you want to do such a conversion while checking to make sure 
that the value will fit in the type being converted to, you can use 
std.conv.to:

auto x = to!uint(-1); //this wil throw
auto y = to!int(uint.max); //this will throw

But the only way to statically prevent such conversions is to wrap your 
integers in structs.

In some ways, making implicit conversions between signed and unsigned types 
would be nice, but you need to convert one to the other often enough, that all 
of the necessary casting could get quite annoying, and if you're using an 
explicit cast rather than std.conv.to, you actually get _less_ safety, because 
the cast will work even if the current implicit conversion wouldn't. For 
example,

int x = -1;
//illegal, except in cases where the compiler can statically determine that
//the conversion won't be truncated (which it could determine in this case,
//but not in the general case).
ushort y = x;

//Legal regardless of the value of x.
ushort z = cast(ushort)x;

So, while disallowing the implicit conversion would have some benefits, there's 
a good chance that it would ultimately cause far more problems than it would 
solve.

- Jonathan M Davis


More information about the Digitalmars-d mailing list