safer casts - take II

Bruno Medeiros brunodomedeiros+spam at com.gmail
Tue Jun 10 08:09:27 PDT 2008


Sorry I'm late.

First of all, I agree with the general principle that D's cast system 
should be more safe. But there are some aspects of your proposal I don't 
agree.

First is the cast(...) vs. cast!(...) syntax. I strongly disagree with 
it, I don't think such constructs should have such a similar syntax, 
particularly sharing the same base name, yet one looking like a function 
call, and the other like a template. I know that the rationale for 
cast!(...) would be to indicate that this is a compile time operation, 
unlike cast(...) but I still don't like it.

But even further than that, I agree with Jason, in that the constancy 
cast construct should not require the type to cast, but just the const 
modifiers. That is, there should only be the forms "cast(const)", 
"cast(invariant)", and "cast(!const)". (Altough cast(!const) should 
really be called cast(mutable) , but that's another issue, about keywords)

Some points were raised against it:

Yigal Chripun wrote:
 > Jason House wrote:
 >> Long ago in one of the const threads, a few people settled on
 >> cast(break const) for what I think you're calling cast!(T). I like
 >> that better than using template syntax to mean less safe.
 >>
 >
 > That's a good point I want to address:
 > initially this is exactly what I proposed, albeit with some minor
 > changes to syntax. [that was: cast(!const) where the ! was meant to be a
 > "not" similar to your break.
 >
 > the problem is that it's not flexible enough.
 > how do you cast the following:
 >     const(invariant(C)*)*  ==> const(C*)* ?
 > this is a contrived example of course, but with cast!(T) you can just 
use:
 >     auto newVal = cast!(const(C*)*)oldVal;
 > this works since this passes the following simple test:
 > if you remove all invariant/const modifiers in both the source and
 > target types you need to get the exact same type. this is to make sure
 > you only change constancy and not the type. in the above case you'll
 > get: ((C)*)*  ==> (C*)* and those two are identical.
 > this only changes constancy and thus legal. had you tried to also change
 > type you'd get an exception.
 >
 > with cast(break const) or cast(!const) this is not possible with just
 > one cast. that kind of shortcut may be considered as well, but since you
 > can always just specify the new constancy of the type this adds very
 > little benefit but adds another syntax rule to the language. I think
 > that Walter probably won't agree to add such a syntax rule and bloat the
 > language without proper justification. with this I 100% sure that I
 > prefer the minimalist approach and do not want to include this in the
 > proposal.
 >
 > feel free to discuss this issue too and suggest use-cases where you
 > think this syntax is needed.

Well, it's true that you couldn't directly do that case "with just one 
cast", but one could define a template that did it with just one call:

   const(invariant(C)*)* foo;
   auto bar = const_cast!(const(C*)*, foo);

So I don't think that would be a problem, right?

Janice Caron wrote:
 > Note that in addition, the ! form would also be the one to use for:
 >
 >     void[] p;
 >     T[] q = cast!(T[])p;
 >
 > So it's not /just/ removal of const that "danger cast" is for. It's
 > also for casting from void to non-void. For that reason, calling it
 > "break const" would be highly counterintuitive.

reinterpret_cast would serve that purpose just fine, wouldn't it?

-- 
Bruno Medeiros - Software Developer, MSc. in CS/E graduate
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D



More information about the Digitalmars-d mailing list