Rant: Date and Time fall short of simplicity in D

Andrej Mitrovic andrej.mitrovich at gmail.com
Sat Mar 30 00:18:08 PDT 2013


On 3/30/13, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> If opCast is defined, it's perfectly
> safe regardless of what would happen if you tried to cast without opCast
> being defined.

Casting is generally unsafe when working with reference types like
classes. For example:

import std.stdio;
final class A
{
    B opCast()
    {
        return new B;
    }
}

class B
{
    void bar() { writeln("B.bar"); }
}

void main()
{
    A a = new A;
    auto b = cast(B)a;
    b.bar();  // no problem
}

Now, remove the opCast, recompile and run and you'll get a segfault.

So a cast is not safe, but you could try using std.conv.to in user-code:

void main()
{
    A a = new A;
    auto b = to!B(a);
    b.bar();
}

This will now throw an exception at runtime. But, notice how it didn't
catch the bug at compile-time. std.conv.to might even catch it at
compile-time if it knows the class doesn't inherit from any
user-defined classes, but generally it can't avoid using a dynamic
cast in a tree hierarchy. It will look for an opCast first, and then
try to do a dynamic cast.

But this is safer and can be caught at compile-time:

import std.stdio;

final class A
{
    T toType(T)()
        if (is(T == B))
    {
        return new B;
    }
}

class B
{
    void bar() { writeln("B.bar"); }
}

T to(T, S)(S s)
    if (__traits(hasMember, S, "toType"))
{
    return s.toType!T();
}

void main()
{
    A a = new A;
    auto b = to!B(a);
    b.bar();
}

If you remove toType, you will get a compile-time error instead of a
runtime one.

The point is to 1) Avoid using casts in user code, and 2) Avoid using
std.conv.to because it's too magical (tries opCast before trying
dynamic cast, which may not be what we want).

There needs to be an explicit handshake between what the library type
provides and what the user wants, cast is just too blunt and is a
red-flag in user-code.


More information about the Digitalmars-d mailing list