initializing const maps with value types having aliasing

Jonathan M Davis jmdavisProg at gmx.com
Wed Mar 20 12:47:48 PDT 2013


On Wednesday, March 20, 2013 20:15:46 Dan wrote:
> On Wednesday, 20 March 2013 at 19:01:27 UTC, Jonathan M Davis
> 
> wrote:
> > Why are you casting? The cast shouldn't be necessary, because
> > you're doing the
> > initialization inside a static constructor.
> 
> Without it I get:
> Error: mutable method cmap.S.__postblit is not callable using a
> const object
> Error: cannot modify struct this Slot with immutable members

postblits do not work with const or immutable. Once you have a postblit, you 
can't copy your object. It's a major problem with postblits. They simply 
fundamentally can't work with them (because the way that they work would 
require modifying a const or immutable variable), and it almost certainly 
means that we're going to need to add copy constructors to the language, but 
that hasn't been sorted out yet.

> > If you had problems, I'd expect it
> > to be that AAs don't work properly when const (I know that
> > there are issues
> > when they're immutable) or that you can't insert elements into
> > a const or
> > immutable AA (which you'll never be able to do). But what
> > you're doing here
> > should work just fine without the cast. Assuming that AAs
> > worked with const or
> > immutable correctly, then it would be normal to do something
> > like
> > 
> > immutable int[string] aa;
> > 
> > static this()
> > {
> > 
> > int[string] temp;
> > temp["foo"] = 7;
> > temp["blah"] = 12;
> > aa = assumeUnique(temp);
> > 
> > }
> 
> For now it seems the cast is necessary - so as long as it is safe.

Well, it may work, but I believe that it's undefined behavior. Casting away 
const and modifying an object is undefined behavior, and while the AA itself 
may not have that problem due to the fact that it's being initialized rather 
than assigned to, the fact that it's working by making a postblit work _is_ 
undefined behavior, because that means that you're modifying a const object 
inside of the postblit constructor.

> I am not using 'immutable S[string]aa', but it would be
> interesting to see how that could be initialized. So, how to
> initialize aa. Does assumeUnique work for associative arrays?
> ------------------
> import std.exception;
> 
> struct S {
> this(this) { x = x.dup; }
> char[] x;
> }
> 
> immutable S[string] aa;
> 
> static this() {
> // now what
> }


All assumeUnique does is cast to immutable. It's just the idiomatic way to 
initialize an immutable variable from a unique mutable object, because it 
makes it clearer what you're doing.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list