digitalmars.D.learn - AA invalidating pointers and references..?
- simendsjo (24/24) Aug 08 2010 unittest
- bearophile (9/22) Aug 08 2010 Yes, a and b are meant to be equal, because they are a reference, that d...
- simendsjo (11/31) Aug 08 2010 1)
- bearophile (23/33) Aug 08 2010 Your examples have shown me that probably the current design can't be ma...
- simendsjo (7/53) Aug 09 2010 You can always use:
unittest { auto a = [1:2]; auto p = 1 in a; // can p be invalidated by rehashing? // That is pointing to a different item or a memory location used for other things? auto b = a.rehash; // The spec also says it orders in place, but returns the reorganized array... // Is the spec right? That it rehashes in place and returns a reference to // itself? assert(a is b); } unittest { auto a = [1:2]; auto p = 1 in a; a.remove(1); // the memory for p can be reassigned by the gc, // so this is undefined behavior.. right? assert(*p == 2); }
Aug 08 2010
simendsjo:auto a = [1:2]; auto p = 1 in a; // can p be invalidated by rehashing?Yes, I presume it can. p is meant for immediate consumption only.// The spec also says it orders in place, but returns the reorganized array... // Is the spec right? That it rehashes in place and returns a reference to // itself? assert(a is b);Yes, a and b are meant to be equal, because they are a reference, that doesn't change. What changes is the data structures referenced by it (if what I have just said turns out to be wrong, then probably it's an implementation bug that needs to be added to bugzilla).auto a = [1:2]; auto p = 1 in a; a.remove(1); // the memory for p can be reassigned by the gc, // so this is undefined behavior.. right?Right, such things show that it's probably better to change the D AA design here: 1) make "x in AA" return a bool 2) improve dmd so it is able to remove most cases of dual lookups in AAs. I will think if this needs to become an enhancement request. Bye, bearophile
Aug 08 2010
On 08.08.2010 17:51, bearophile wrote:simendsjo:Ok, thanks.auto a = [1:2]; auto p = 1 in a; // can p be invalidated by rehashing?Yes, I presume it can. p is meant for immediate consumption only.// The spec also says it orders in place, but returns the reorganized array... // Is the spec right? That it rehashes in place and returns a reference to // itself? assert(a is b);Yes, a and b are meant to be equal, because they are a reference, that doesn't change. What changes is the data structures referenced by it (if what I have just said turns out to be wrong, then probably it's an implementation bug that needs to be added to bugzilla).1) I haven't worked much with AA's, but I find the "key in aa returns a reference to the value" to be handy. I think it's better than the following: int value; if( 1 in a ) value = a[1]; or a[1] in a try/catch or other implementations. 2) I don't know what you mean. Does a single lookup often involve several under the hood?auto a = [1:2]; auto p = 1 in a; a.remove(1); // the memory for p can be reassigned by the gc, // so this is undefined behavior.. right?Right, such things show that it's probably better to change the D AA design here: 1) make "x in AA" return a bool 2) improve dmd so it is able to remove most cases of dual lookups in AAs. I will think if this needs to become an enhancement request.
Aug 08 2010
simendsjo:I haven't worked much with AA's, but I find the "key in aa returns a reference to the value" to be handy. I think it's better than the following: int value; if( 1 in a ) value = a[1]; or a[1] in a try/catch or other implementations.Your examples have shown me that probably the current design can't be made safe, and you can't use in SafeD code. But performing "x in AA" is a very useful operation that I want to perform in SafeD code. And in my opinion this code: int value; auto ptr = 1 in a; if (ptr) value = *ptr; Doesn't look better than: int value; if (1 in a) value = a[1];2) I don't know what you mean. Does a single lookup often involve several under the hood?If your compiler is naive then code like this: if (1 in a) value = a[1]; requires to perform two searches inside the hash, the first to tell if the key is present, and the second to find it again and fetch its value. A bit better compiler (LDC is already able to do this) can recognize that you are performing two nearby key searches with the same key, and it can remove the second one, essentially replacing that code with this one: int value; auto ptr = 1 in a; if (ptr) value = *ptr; Bye, bearophile
Aug 08 2010
bearophile wrote:simendsjo:You can always use: auto value = 1 in a; if (value) // needs != null? Haven't looked at this in the spec yet. //work with *value But if the compiler can optimize the calls either way, and this is unsafe, a safer way sounds nice.I haven't worked much with AA's, but I find the "key in aa returns a reference to the value" to be handy. I think it's better than the following: int value; if( 1 in a ) value = a[1]; or a[1] in a try/catch or other implementations.Your examples have shown me that probably the current design can't be made safe, and you can't use in SafeD code. But performing "x in AA" is a very useful operation that I want to perform in SafeD code. And in my opinion this code: int value; auto ptr = 1 in a; if (ptr) value = *ptr; Doesn't look better than: int value; if (1 in a) value = a[1];2) I don't know what you mean. Does a single lookup often involve several under the hood?If your compiler is naive then code like this: if (1 in a) value = a[1]; requires to perform two searches inside the hash, the first to tell if the key is present, and the second to find it again and fetch its value. A bit better compiler (LDC is already able to do this) can recognize that you are performing two nearby key searches with the same key, and it can remove the second one, essentially replacing that code with this one: int value; auto ptr = 1 in a; if (ptr) value = *ptr; Bye, bearophile
Aug 09 2010