digitalmars.D.bugs - Bad AA behavior
- BCS <BCS pathilink.com> Dec 23 2006
- Dave <Dave_member pathlink.com> Dec 23 2006
- BCS <BCS pathilink.com> Dec 23 2006
- Kirk McDonald <kirklin.mcdonald gmail.com> Dec 24 2006
- Serg Kovrov <kovrov no.spam> Dec 26 2006
- %u <it set.com> Dec 24 2006
- BCS <BCS pathilink.com> Dec 24 2006
- %u <u digitaldaemon.com> Dec 25 2006
- BCS <BCS pathilink.com> Dec 27 2006
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: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
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.
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: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).
I have stepped on arrays-related rakes in D, oh-so-many times... Wonder what Walter will comment on that one. -- serg.
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 articleset[it] = 0;
This should read set[it.dup] = 0;
This is my point, actual. Doing anything else is asking for trouble, so why doesn't the runtime do it for you?
Dec 24 2006
== Quote from BCS (BCS pathilink.com)'s articleDoing anything else is asking for trouble
No. 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 articleDoing anything else is asking for trouble
No. 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.
OK 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.
Dec 27 2006









Serg Kovrov <kovrov no.spam> 