Rant: Date and Time fall short of simplicity in D
Artur Skawina
art.08.09 at gmail.com
Sat Mar 30 01:15:24 PDT 2013
On 03/30/13 07:12, Jonathan M Davis wrote:
> On Friday, March 29, 2013 22:46:27 Steven Schveighoffer wrote:
>> The issue is when you think you are invoking the opCast operator, but you
>> inadvertently end up casting using the compiler's type-bypassing version.
>> I agree the opCast call is safe, it's that its name coincides with the
>> "throw all typechecks away" operator.
>
> I'd have to experiment to see exactly what is and isn't accepted, but in my
> experience, the compiler rarely allows casting to or from structs without
> opCast (the same with classes except for the inheritance tree). So, I really
> don't think that there's much risk of accidentally using a cast on a user-
> defined type and have it use the built-in cast operator.
>
>> I don't think to should ignore opCast, or not use it, but there should be
>> a way to hook 'to' without using opCast. And most types should prefer
>> that.
>
> I really just don't see a problem here. If opCast is defined, it's perfectly
> safe regardless of what would happen if you tried to cast without opCast being
> defined. It's also the language-defined way to do type conversions. And I really
> don't see any need to use anything else to make std.conv.to work. By using
> opCast, there's a standard way to define type conversion, and there's a
> standard way for it to hook into std.conv.to, which seems way better to me
> than trying to support every which way that a particular programmer wants to
> try and define a conversion function. Clearly, you think that using opCast is a
> problem, but I just don't agree. It's safe; it's standard; and it works.
struct S {
ubyte[] p;
}
import std.stdio;
void main() {
immutable a = S(null);
// ...
auto b = cast(S)a;
writeln(typeof(a.p).stringof);
writeln(typeof(b.p).stringof);
}
which can easily happen in generic code. And you can't tell w/o looking
at the S implementation whether it's safe or not (with an appropriate
opCast it could be).
'cast()' is special, so you can't even use a "safer" opCast like
auto opCast(DT)() inout { return inout(DT)(this.tupleof); }
// or, more likely, returning some templated object instance
because a different return type is not accepted. Using a method
auto b = a.opCast!S();
avoids these problems -- you only have to provide a correct a.opCast
implementation and the compiler will then catch caller mistakes.
'cast' /is/ dangerous, separating the safe operations from the
potentially unsafe ones is desirable. Most of the bugs caused by
mistakenly dropping 'const' etc wouldn't have happened if the explicit
casts weren't there - because the compiler would have complained,
forcing the coder to consider if the conversion really is necessary
and how to handle it properly.
artur
More information about the Digitalmars-d
mailing list