Safer casts
Robert Fraser
fraserofthenight at gmail.com
Fri May 9 11:25:55 PDT 2008
janderson wrote:
> 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
I think Janice mentioned that it would work exactly like that.
More information about the Digitalmars-d
mailing list