develooper 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About