Front page | perl.perl5.porters |
Postings from September 2016
hv.h hek definition
Thread Previous
|
Thread Next
From:
Todd Rinaldo
Date:
September 29, 2016 02:52
Subject:
hv.h hek definition
Message ID:
3A3D3E33-5377-4078-B411-2354307DF5BA@cpanel.net
Excerpt from hv.h:
/* hash key -- defined separately for use as shared pointer */
struct hek
{
U32 hek_hash; /* hash of key */
I32 hek_len; /* length of hash key */
char hek_key[1]; /* variable-length hash key */
/* the hash-key is \0-terminated */
/* after the \0 there is a byte for flags, such as whether the key
is UTF-8 */
};
IMO, the declaration for hek_key is VERY misleading. In the context of a struct, what you end up with when you do char hek_key[1]; is a char pointer followed by a char. We exploit that to store the flags in the char slot and we inject a string pointer in hek_key.
The comments are misleading and wrong AFAIK, the string does not have flags on the end of it. instead they're stored in the byte on the tail of the struct:
#define HEK_FLAGS(hek) (*((unsigned char *)(HEK_KEY(hek))+HEK_LEN(hek)+1))
I can see no reason why this should be written this way. It is also difficult to populate this struct from C because the char* is mixed in with the char. C doesn't like you altering the char pointer. This seems much more intuitive and legible:
struct hek
{
U32 hek_hash; /* hash of key */
I32 hek_len; /* length of hash key */
char *hek_key; /* hash key pointer */
char flags; /* hek flags such as whether the key is UTF-8 */
};
Is there some obscure compiler subtlety that caused us to originally define it this way back in the old days? Is there a reason it shouldn't be fixed?
Thanks,
Todd
Thread Previous
|
Thread Next