object.d and hash_t confusion?

kris foo at bar.com
Wed Jun 21 16:06:39 PDT 2006


In object.d, there's an alias declaration for hash_t like so:

------------
alias size_t hash_t;
-----------

This indicates that the hash_t type will be 32bit on a 32bit system, and 
64bit on that system; yes? Is this so that a pointer can be directly 
returned as a hash value?

Then, also in object.d, we have the decl for class Object:

-----------
class Object
{
     void print();
     char[] toString();
     uint toHash();
     int opCmp(Object o);
     int opEquals(Object o);
}
-----------

Notice that the toHash() method returns a uint? Is that supposed to be 
hash_t instead?

For the moment, let's suppose it is meant to be hash_t. The rest of this 
post is based upon that notion, so if I'm wrong here, no harm done :)

Using hash_t as the return type would mean the toHash() method returns a 
different type depending upon which platform it's compiled upon. This 
may have some ramifications, so let's explore what they might be:

1) because an alias is used, type-safety does not come into play. Thus, 
when someone overrides Object.toHash like so:

------------
override uint toHash() {...}
------------

a 32bit compiler will be unlikely to complain (remember, hash_t is an 
alias).

When this code is compiled in 64bit land, luckily, the compiler will 
probably complain about the uint/ulong mismatch. However, because the 
keyword "override" is not mandatory, most programmers will do this 
instead (in an class):

-----------
uint toHash() {....}
-----------

the result will perhaps be a good compile but a bogus override? Or will 
the compiler flag this as not being covariant? Either way, shouldn't 
this be handled in a more suitable manner?

I suppose one way to ensure consistency is to use a typedef instead of 
an alias ... but will that cause errors when the result is used in an 
arithmetic expression? In this situation, is typedef too type-safe and 
alias not sufficient?


2) It's generally not a great idea to change the signature/types of 
overridable methods when moving platforms. You have to ensure there's 
absolute consistency in the types used, otherwise the vaguely brittle 
nature of the override mechanism can be tripped.

So the question here is "why does toHash() need to change across 
platforms?". Isn't 32bits sufficient?

If the answer to that indicates a 64bit value being more applicable 
(even for avoiding type-conversion warnings), then it would seem to 
indicate a new integral-type is required? One that has type-safety (a la 
typedef) but can be used in arithmetic expression without warnings or 
errors? This new type would be equivalent to size_t vis-a-vis byte size.

I know D is supposed to have fixed-size basic integer types across 
platforms, and for good reason. Yet here's a situation where, it *seems* 
that the most fundamental class in the runtime is perhaps flaunting 
that? Perhaps there's a few other corners where similar concerns may 
crop up?

I will note a vague distaste for the gazilion C++ style meta-types 
anyway; D does the right thing in making almost all of them entirely 
redundant. But, if there is indeed a problem with toHash(), then I 
suspect we need a more robust solution. What say you?



More information about the Digitalmars-d mailing list