digitalmars.D.bugs - Bad AA behavior
- BCS (12/12) Dec 23 2006 void main()
- Dave (20/34) Dec 23 2006 I believe it is correct because of the distinction between value and ref...
- BCS (17/63) Dec 23 2006 Good point. But what about this
- Kirk McDonald (7/27) Dec 24 2006 And this is why dictionary keys are required to be immutable in Python
- Serg Kovrov (5/16) Dec 26 2006 I have stepped on arrays-related rakes in D, oh-so-many times...
- %u (3/4) Dec 24 2006 This should read
void main() { byte[char[]] set; char[] it = "it".dup; set[it] = 0; assert("it" in set); // pass it[0] = 'a'; it[1] = 'a'; assert("it" in set); // fail } This can't be correct. Anyone second that?
Dec 23 2006
BCS wrote:void main() { byte[char[]] set; char[] it = "it".dup; set[it] = 0; assert("it" in set); // pass it[0] = 'a'; it[1] = 'a'; assert("it" in set); // fail } This can't be correct.I believe it is correct because of the distinction between value and reference types made throughout D. I don't find the behavior inconsistent, although I've been bitten by it once or twice so I'd agree that it's not always intuitive. byte[char[]] set; // is an array of bytes indexed by char[]'s (a reference type) //set[it] = 0; set[it.dup] = 0; // this (obviously) will do what you expect To get the behavior you suggest (and be consistent), then UDT's would all have to have a copy ctor, either explicit or implicit. If implicit, then how is the compiler supposed to do a deep copy on objects defined like: class C { char* ptr; //... } ? If manual memory management for D was the norm, then I'd say you have a much stronger argument. But since GC is the norm. (and in part because GC is the norm D also does away with copy ctor's) the current behavior is correct, IMHO. - Dave
Dec 23 2006
Dave wrote:BCS wrote:Good point. But what about this void main() { byte[char[]] set; char[] it = "it".dup; set[it] = 0; assert("it" in set); // pass it[0] = 'a'; it[1] = 'a'; assert(set.keys[0] in set); // fail } Furthermore, once the underling data is changed, the member can't be accessed even to remove it. set.remove(set.keys[0]); // has no effect I'll admit that I don't known what to do with the object/struct case, but I think the current behavior isn't good.void main() { byte[char[]] set; char[] it = "it".dup; set[it] = 0; assert("it" in set); // pass it[0] = 'a'; it[1] = 'a'; assert("it" in set); // fail } This can't be correct.I believe it is correct because of the distinction between value and reference types made throughout D. I don't find the behavior inconsistent, although I've been bitten by it once or twice so I'd agree that it's not always intuitive. byte[char[]] set; // is an array of bytes indexed by char[]'s (a reference type) //set[it] = 0; set[it.dup] = 0; // this (obviously) will do what you expect To get the behavior you suggest (and be consistent), then UDT's would all have to have a copy ctor, either explicit or implicit. If implicit, then how is the compiler supposed to do a deep copy on objects defined like: class C { char* ptr; //... } ? If manual memory management for D was the norm, then I'd say you have a much stronger argument. But since GC is the norm. (and in part because GC is the norm D also does away with copy ctor's) the current behavior is correct, IMHO. - Dave
Dec 23 2006
BCS wrote:Good point. But what about this void main() { byte[char[]] set; char[] it = "it".dup; set[it] = 0; assert("it" in set); // pass it[0] = 'a'; it[1] = 'a'; assert(set.keys[0] in set); // fail } Furthermore, once the underling data is changed, the member can't be accessed even to remove it. set.remove(set.keys[0]); // has no effect I'll admit that I don't known what to do with the object/struct case, but I think the current behavior isn't good.And this is why dictionary keys are required to be immutable in Python (and numbers, strings, and tuples are all immutable types). -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org
Dec 24 2006
Kirk McDonald wrote:BCS wrote:I have stepped on arrays-related rakes in D, oh-so-many times... Wonder what Walter will comment on that one. -- serg.Furthermore, once the underling data is changed, the member can't be accessed even to remove it. set.remove(set.keys[0]); // has no effect I'll admit that I don't known what to do with the object/struct case, but I think the current behavior isn't good.And this is why dictionary keys are required to be immutable in Python (and numbers, strings, and tuples are all immutable types).
Dec 26 2006
== Quote from BCS (BCS pathilink.com)'s articleset[it] = 0;This should read set[it.dup] = 0;
Dec 24 2006
%u wrote:== Quote from BCS (BCS pathilink.com)'s articleThis is my point, actual. Doing anything else is asking for trouble, so why doesn't the runtime do it for you?set[it] = 0;This should read set[it.dup] = 0;
Dec 24 2006
== Quote from BCS (BCS pathilink.com)'s articleDoing anything else is asking for troubleNo. In case the coder knows that the key is immutable a duplication is superfluous. A superfluous duplication is dangerous if the duplicated key is relatively large to the remaining free memeory.
Dec 25 2006
%u wrote:== Quote from BCS (BCS pathilink.com)'s articleOK so you end up asking for trouble either way. I still don't /like/ it, and will still live with it. maybe some note should be added to the AA section of the docs.Doing anything else is asking for troubleNo. In case the coder knows that the key is immutable a duplication is superfluous. A superfluous duplication is dangerous if the duplicated key is relatively large to the remaining free memeory.
Dec 27 2006