On Sunday, January 08, 2012 13:06:06 simendsjo wrote: > Certainly not obvious to me :)
Well, what's obvious to one person is not always obvious to another. I'm sure that there are plenty of things that Walter thinks should be perfectly obvious which 90% of programmers would never think of. A lot of it depends on what you're experience level is and what you have experience in. In this case, it's very much like dealing with C++ iterators, so if you're used to dealing with them and when they do or don't get invalidate, then the situation with in and remove is probably quite straightforward and intuitive. > auto c = new C(); > C[string] aa; > aa["c"] = c; > aa.remove("c"); > > I guess using c from this point is valid, but if the only reference to c > was inside the aa (and we got c using `in`), using c would have been > undefined..? Using c is valid regardless. The problem is the in operator. It returns a pointer to the element inside of the AA. So, if you did C* d = aa["c"]; then d would be a pointer to a reference to a C, and after the call to remove, the pointer is pointing to memory which may or may not be part of the AA anymore and which may or may not hold a reference to what c refers to. It's bit like doing this int* a() { int b; return &b; } though the compiler should catch this, since it's obviously wrong. In both cases, you're referring to memory which your really not supposed to be accessing anymore and may point to invalid memory. The case of the AA probably isn't as bad, since either you're pointing to memory on the GC which isn't part of the AA (but hasn't been collected, since you have a pointer to it), or you're pointing to an element in the AA which may still be the same as it was before it was removed, or it may be another element, or it may be garbage memory. You really don't know. It's undefined and therefore shouldn't be used. I don't believe that it's ever safe to assume that the pointer returned by the in operator is still valid after the AA that it comes from has had an element added or removed. It's the same with iterators or ranges with many iterators and ranges. If they point to elements within a container, and that container is altered, they're invalidated and aren't safe to use. So, your example is fine, because it doesn't involve the in operator, and therefore doesn't involve any pointers into the AA. It's only once you have pointers into the AA that you get into trouble. - Jonathan M Davis