develooper Front page | perl.perl5.porters | Postings from September 2016

hv.h hek definition

Thread Previous
From:
YAPC Admin
Date:
September 29, 2016 19:32
Subject:
hv.h hek definition
Message ID:
2E91CD51-CC06-492A-A549-228433A17CCF@yapcna.org
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


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