Incomplete knowledge + all powerful casts = troubles
bearophile
bearophileHUGS at lycos.com
Mon Sep 19 10:23:32 PDT 2011
This is a simplified version of some older D code of mine.
The cast is needed to convert int->uint:
uint foo(T)(T x) if (is(T == uint)) {
uint ans = 0;
while (x >>= 1)
ans++;
return ans;
}
void bar(int x) {
auto xx = foo(cast(uint)x);
}
void main() {}
I have "improved" it adding a nice "in" in the bar() signature. The code compiles and runs still:
uint foo(T)(T x) if (is(T == uint)) {
uint ans = 0;
while (x >>= 1)
ans++;
return ans;
}
void bar(in int x) {
auto xx = foo(cast(uint)x);
}
void main() {}
Unfortunately now the code contains a small bug. The cast now converts const(int)->uint, and foo() will modify a const value, that gives undefined effects in D2.
D1 has only "const" (that is "enum" of D2), so I think a single kind of cast() is enough in D1. But D2 has const/immutable too (and other tags) so I think a single kind of cast is now a bit short.
If Phobos (or D2 itself) adds a kind of const_cast!(), _and_ the power of D cast() is reduced removing its ability to remove attributes like const/immutable from a type, the bug I have created doesn't happen, but it looks a bit messy:
const(int) x;
auto y = cast(uint)x;
static assert(is(typeof(y) == const(uint)));
auto z = const_cast!uint(x);
static assert(is(typeof(z) == uint));
What do you think?
A cast means punching a hole in the type system, so the programmer has to use it with care. The problems are born from the programmer not having a complete knowledge of the situation (the types involved) when he/she uses the cast, or as in this case when I have later modified the code.
The example shown in this post is only the last one I have found. Casts now and then cause me small troubles.
This is not the first time we discuss about casts, and probably it isn't the last one :-)
Bye,
bearophile
More information about the Digitalmars-d
mailing list