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