On Thu, 02 Jun 2011 17:52:41 -0400, Jonathan M Davis
<jmdavisp...@gmx.com>
wrote:
> On 2011-06-02 09:02, Bruno Medeiros wrote:
>> On 01/06/2011 22:12, Jonathan M Davis wrote:
>> >> It's nice in a way, but it's all based on the way cast handles
>> >> modifiers.
>> >>
>> >> > And I've always been a bit unconfortable with how that's handled
>>
>> (In
>>
>> >> > fact, I was just thinking about this yesterday). Specifically,
it
>> >> > seems extremely bad that it's so incredibly easy to accidentaly
>>
>> cast
>>
>> >> > away things like const and immutable:
>> >> >
>> >> > For example, if I know I have an array of uint's, and I want to
>>
>> deal
>>
>> >> > with the individual bytes, it's perfectly safe and sensible to
cast
>> >> > it to a ubyte[] (a long as you factor in endianness, of course).
>>
>> So,
>>
>> >> > you do "cast(ubyte[])myArray". But, OOPS!!: If myArray happened
to
>> >> > be immutable, then merely trying to cast the type has
inadvertantly
>> >> > cast-away immutable. Not good! Casting away const/immutable
really,
>> >> > really should have to be explict.
>> >> >
>> >> > Of course, you can probably use some fancy helper templates to
make
>> >> > sure you preserve all modifiers. But needing to do so is just
>>
>> asking
>>
>> >> > for mistakes: it seems like a huge violation of "make the right
way
>> >> > easy, and the wrong way hard".
>> >
>> > You really shouldn't be casting much anyway. It's the sort of
feature
>> > where you're only supposed to use it when you know what you're
doing
>> > when you use it. And if there's really any possibility that you're
>> > dealing with immutable, perhaps you should be casting to const
rather
>> > than mutable. Personally, I find how C++ created multiple types of
>>
>> cast
>>
>> > (include const_cast)_highly_ annoying and generally useless, and
>> > I'm_very_ glad that D didn't do anything of the sort.
>> >
>> > - Jonathan M Davis
>>
>> "you're only supposed to use it when you know what you're doing when
you
>> use it"
>> Well, that's kinda the requirement for any feature, isn't it?... :P
>> Well, kinda, I do know what you mean. Yes, one needs to properly
learn
>> how cast() works, but that doesn't mean it would not be better for
the
>> feature to be designed in a way that is easier to learn (and just as
>> powerful to use), or actually, it doesn't mean that even if you do
know
>> how cast() works, that you are not still likely to make a mistake
when
>> using it.
>
> Really, you should only be using casts when you need a cast, and you
> should be
> careful when you use them. So, you have to know what you're doing and
> why in
> that particular instance and not use them willy-nilly. In most code,
> casts
> should be quite rare. If you're doing a lot of low-level stuff, then
they
> might be more common, but in general, they're a sledgehammer that
> shouldn't be
> used except when you really need them.
Casting is the recommended way to determine if something is actually a
derived type:
interface I {}
class C : I {}
void foo(I i) // change this to const(I) and you have a huge const bug!
{
if(C c = cast(C)i)
{
// optimized branch
}
else
{
// default branch
}
}
so it's not so easy to say you should "never" cast. BTW, dcollections
uses this quite a bit to support operations between multiple types of
collections.
It would be nice if at least dynamic cast (with the added rules to
prevent
casting away const/immutable/shared) was a different syntax from cast,
since it's a completely safe usage of casting (as long as you manually
forward modifiers). It's as safe as to! is when used with the right
context.