On 7 Jul 2009, at 16:31, Niels Grewe wrote: > I've just tried to compile the svn tree on my 64bit machine and ran > into > the following issue: The ETObjectMirror class in the new reflection > code > uses the address of the object it is mirroring as its hash. > Unfortunately the unsigned int to which the pointer is cast will cause > it to be truncated, possibly causing collisions between the hashes of > mirrors of unrelated objects.
Collisions don't matter with -hash, they are expected. The requirement is that if [a isEqual: b] then [a hash] == [b hash]. There is no requirement that unrelated objects may not have the same hash. > Unfortunately, GNUstep has not yet made the switch to the Mac OS > 10.5-style definition of NSUInteger, which would just make this a > non-issue because it would always be sized properly. It did a while ago, perhaps you are using an old version. That said, NS[U]integer is equivalent to C99's [u]intptr_t, and since we require C99 you can use these instead. I've just checked, and -hash is declared as returning an NSUInteger on GNUstep. The correct fix for this is just to change the return type of -hash in ETReflection.m to match the GNUstep version. > I've attached a little workaround, which will use the hash of the > object > if available and only fall back to the address otherwise. This way, > the > truncation will only be a problem if you are on 64bit, have more than > 4GB RAM, and the object does not conform to NSObject, which should be > quite rare. Note that you can, and frequently do, get pointers that are above the 4GB line even if you have less than 4GB of RAM. Processes still have more than 4GB of virtual address space, irrespective of the amount of physical RAM on a 64-bit system (typically around 48 bits of space). On an operating system with address space randomisation this is very common. > I just wanted to check back prior to commiting that there > isn't some rationale behind not using -hash at this place. This looks like an attempt at an optimisation. The two instances are only equal if they point to the same object, so you can use the object pointer as a hash, which can make collections slightly more efficient. -hash is expected to be faster than -isEqual: so it's used as an optimisation in a number of collections. For example, if you tell an array to delete any objects equal to an object, it will first scan through the array sending -hash to all of the elements. It will then send -isEqual: to the ones that return the same hash as the original. This is faster than sending -isEqual: to every object. David _______________________________________________ Etoile-dev mailing list Etoile-dev@gna.org https://mail.gna.org/listinfo/etoile-dev