uthash uses memcmp to compare keys. For the benefit of platforms where the native libc contains bcmp-but-not-memcmp, we provide a customization point uthash_memcmp so that the user can compile with
gcc main.c -Duthash_memcmp=bcmp
However, this is misleading because it implies more constraints than there actually are:
bcmp doesn't actually give the same postconditions as memcmp. bcmp tests equality and returns only "zero or non-zero", whereas memcmp tests ordering and returns "negative, zero, or positive". So bcmp is not a drop-in replacement for memcmp; yet it is still a valid replacement for uthash_memcmp.
On the mailing list, someone asked how to use uthash with arbitrary struct keys (containing padding, nested pointers, etc). I suggested to -DHASH_FUNCTION=mystruct_get_hash. This swaps out the comparison function easily enough; but it won't work out of the box unless you also -Duthash_memcmp=mystruct_isnt_equal. Again, mystruct_isnt_equal is even more clearly not a drop-in replacement for memcmp in general; but doing the replacement is the right thing to do in this case (arguably).
So I claim that uthash_memcmp is misnamed, and it should have a name that more accurately reflects what it does — for example, HASH_KEYCOMPARE(k1, k2, keylen).
This would also serve the (arguably bad-idea) purposes of users who want to -DHASH_KEYCOMPARE(...)=0 to "save" the cost of a memcmp on each bucket element (in exchange for occasional wrong results in the presence of hash collisions — collisions that start to become expected in the tens-of-thousands-of-elements range).
The question is, if we introduce HASH_KEYCOMPARE, what do we do with uthash_memcmp? My suggestion is
uthash uses
memcmp
to compare keys. For the benefit of platforms where the native libc containsbcmp
-but-not-memcmp
, we provide a customization pointuthash_memcmp
so that the user can compile withHowever, this is misleading because it implies more constraints than there actually are:
bcmp
doesn't actually give the same postconditions asmemcmp
.bcmp
tests equality and returns only "zero or non-zero", whereasmemcmp
tests ordering and returns "negative, zero, or positive". Sobcmp
is not a drop-in replacement formemcmp
; yet it is still a valid replacement foruthash_memcmp
.-DHASH_FUNCTION=mystruct_get_hash
. This swaps out the comparison function easily enough; but it won't work out of the box unless you also-Duthash_memcmp=mystruct_isnt_equal
. Again,mystruct_isnt_equal
is even more clearly not a drop-in replacement formemcmp
in general; but doing the replacement is the right thing to do in this case (arguably).So I claim that
uthash_memcmp
is misnamed, and it should have a name that more accurately reflects what it does — for example,HASH_KEYCOMPARE(k1, k2, keylen)
.This would also serve the (arguably bad-idea) purposes of users who want to
-DHASH_KEYCOMPARE(...)=0
to "save" the cost of a memcmp on each bucket element (in exchange for occasional wrong results in the presence of hash collisions — collisions that start to become expected in the tens-of-thousands-of-elements range).The question is, if we introduce
HASH_KEYCOMPARE
, what do we do withuthash_memcmp
? My suggestion isfor one point release, and then for the next point release we change it to