Accidentally killing immutable is too easy in D (Was: cast()x - a valid expression?)

Jonathan M Davis jmdavisProg at gmx.com
Wed Jun 1 14:12:01 PDT 2011


On 2011-06-01 13:42, Nick Sabalausky wrote:
> "Steven Schveighoffer" <schveiguy at yahoo.com> wrote in message
> news:op.vwex37voeav7ka at localhost.localdomain...
> 
> > On Wed, 01 Jun 2011 15:38:32 -0400, Andrej Mitrovic
> > 
> > <andrej.mitrovich at gmail.com> wrote:
> >> It seems to do even more than that:
> >> int a;
> >> const int b;
> >> immutable int c;
> >> shared int d;
> >> shared(const int) e;
> >> 
> >> static assert(is(typeof(cast()a) == int));
> >> static assert(is(typeof(cast()b) == int));
> >> static assert(is(typeof(cast()c) == int));
> >> static assert(is(typeof(cast()d) == int));
> >> static assert(is(typeof(cast()e) == int));
> >> 
> >> Talk about stealing the storm from std.traits.Unqual..
> >> 
> >> On 6/1/11, KennyTM~ <kennytm at gmail.com> wrote:
> >>> While checking the Phobos source I've found an interesting expression
> >>> 
> >>> cast()(result[i]) = to!(E)(e);
> >>> 
> >>> The 'cast()' means 'cast to mutable', e.g.
> >>> 
> >>> class S {}
> >>> void g(S x) {}
> >>> void main() {
> >>> 
> >>> const S s;
> >>> g(cast()s);
> >>> 
> >>> }
> >>> 
> >>> But this is not documented in the D spec (CastParam cannot be empty).
> >>> Is this an "accept-invalid" bug, or just a feature not yet documented?
> > 
> > It gets even better:
> > 
> > char[] x = "abc".dup;
> > 
> > assert(is(typeof(cast(const)x) == const(char[]));
> > 
> > I think you may have found a "bug" that should be a feature. It's like
> > dmd is organically growing features that we might need ;) Is this
> > software evolution? Scary!
> > 
> > When will dmd decide that human life is a disease to be eradicated? When
> > will the world be dominated by constinators?!!! I fear for my children.
> > 
> > All kidding aside, I actually think the syntax makes sense. You are
> > adding/removing modifiers, so just leave the type out of it. The only
> > drawback is, you can't do a cast directly to a tail-const array, but
> > that's not a huge deal, since const(T[]) implicitly casts to const(T)[].
> > 
> > I dub this feature "Type Modifier Casting".
> 
> 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


More information about the Digitalmars-d mailing list