digitalmars.D.learn - initializing const maps with value types having aliasing
- Dan (22/22) Mar 20 2013 The following works and is the only way I have found to
- Jonathan M Davis (17/44) Mar 20 2013 Why are you casting? The cast shouldn't be necessary, because you're doi...
- Dan (22/44) Mar 20 2013 Without it I get:
- Jonathan M Davis (17/69) Mar 20 2013 postblits do not work with const or immutable. Once you have a postblit,...
- bearophile (11/13) Mar 20 2013 I think I have never seen code like that. What's the meaning? :-)
The following works and is the only way I have found to initialize m. Unfortunately it requires the cast. Is this safe to do? Is there a better way? Is this a bug or are future features coming to clean it up? Thanks Dan ---------------------------------- import std.stdio; struct S { this(this) { x = x.dup; } char[] x; } const(S[string]) m; static this() { // Is there a cleaner way? cast(S[string])m = [ "foo" : S(['a']) ]; } void main() { writeln(m["foo"]); }
Mar 20 2013
On Wednesday, March 20, 2013 19:41:00 Dan wrote:The following works and is the only way I have found to initialize m. Unfortunately it requires the cast. Is this safe to do? Is there a better way? Is this a bug or are future features coming to clean it up? Thanks Dan ---------------------------------- import std.stdio; struct S { this(this) { x = x.dup; } char[] x; } const(S[string]) m; static this() { // Is there a cleaner way? cast(S[string])m = [ "foo" : S(['a']) ]; } void main() { writeln(m["foo"]); }Why are you casting? The cast shouldn't be necessary, because you're doing the initialization inside a static constructor. 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); } - Jonathan M Davis
Mar 20 2013
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 membersIf 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. 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 } Thakns Dan
Mar 20 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: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.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 membersWell, 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.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.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
Mar 20 2013
Dan:this(this) { x = x.dup; }I think this(this) doesn't work well with const.cast(S[string])m = [ "foo" : S(['a']) ];I think I have never seen code like that. What's the meaning? :-) (Also if you remove that cast then dmd gives bad error messages with no line numbers: Error: mutable method temp.S.__postblit is not callable using a const object Error: cannot modify struct this Slot with immutable members ). Bye, bearophile
Mar 20 2013