Safer casts
janderson
askme at me.com
Fri May 9 08:05:11 PDT 2008
Janice Caron wrote:
> Better, safer casts have been requested before - in fact I routinely
> see that request on the monthly "D wishlist" that goes round. But
> here's a fairly concrete suggestion as to what the syntax might be.
> And as a bonus, we'd get rid of the "cast" keyword, thus reducing the
> keyword count by one. So, here are the various types of transformation
> I suggest:
>
>
> (*) Build a new instance with a different memory layout, but with the
> same value. (For example, casting double to int). For lossless
> conversions, this can happen implicitly, but for lossy conversions, an
> explicit cast is necessary. For D, I suggest
>
> to!(T)(x)
>
> where to! is a template function provided by std.conv (not a keyword).
> to! already performs many conversions. Throwing in the basics like
> to!(int)(double) would be an obvious extension.
>
>
>
> (*) Use RTTI to cast up and down the class heirarchy. In C++, this
> would be dynamic_cast<T>(x). For D, I suggest two things. Firstly, the
> cast:
>
> class!(T)(x)
>
> to do that actual upcast or downcast - but RTTI dynamic casts can
> fail, so the question arises: What should we do if the cast fails?
> Should we return null, or should we throw an exception. My view is
> that we should throw an exception, but also introduce a new construct
> to test whether or not the cast would be possible in the first place:
>
> is!(T)(x)
>
> which returns bool. is!(T) would be like Java's instanceof. Thus, one
> could write
>
> void f(A a)
> {
> if (is!(B)a)
> {
> B b = class!(B)(a);
> /*...*/
> }
> else if (is!(C)a)
> {
> C c = class!(C)(a);
> /*...*/
> }
> }
>
> etc.
>
>
> (*) Reinterpret a bit pattern. In C++, this would be
> reinterpret_cast<T>(x). Without changing the memory layout, or the
> constancy, reinterpret the bits to mean something else. For D, I
> suggest
>
> union!(T)(x)
>
>
> (*) Change const to mutable, or invariant to mutable. In C++, this
> would be const_cast<T>(x). There is no equivalent in D, however, in D,
> one can currently write cast(T)x, and constancy will be magically (and
> dangerously) waved away. In the new scheme, I suggest:
>
> auto!(T)(x)
>
>
>
> (*) Change const to invariant, or mutable to invariant. Currently, the
> syntax for this is cast(invariant)x, however this has two
> disadvantages: (i) the entire type is made invariant, and you might
> want to invariantize only part of the type, and (ii) cast(T)x also
> works. In other words, (i) is not powerful enough, and (ii) is too
> dangerous. There is no equivalent for this in C++, since C++ has no
> invariance. For D, I suggest:
>
> invariant!(T)(x)
>
>
>
> I think that's all bases covered. So in summary we'd have:
>
> to!(T)(x) // convert
> is!(T)(x) // is upcast or downcast possible?
> class!(T)(x) // upcast or downcast
> union!(T)(x) // reinterpret the bits
> auto!(T)(x) // remove constancy
> invariant!(T)(x) // add invariance
>
>
> Those seem reasonably obvious word choices to me. Thoughts?
I think that up casting for classes should be implicit, like it works in
C++. Its perfectly ok to upcast and there shouldn't be any warning
casts around that. That is actually a very useful feature for genetic
style coding. Of course the cast should still work for upcasting, but
its superfluous.
-Joel
More information about the Digitalmars-d
mailing list