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