Understanding the benefits of handling Bucket data in PHP's HashTables
| From: | Jeff Brown | Date: | Thu, 16 Sep 2010 09:56:59 +0000 |
| Subject: | Understanding the benefits of handling Bucket data in PHP's HashTables | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-49698@lists.php.net to get a copy of this message | ||
Hey guys (and girls),
I have been reading this list for sometimebut this is the first time I'm actually posting
something.This might fit better in a C\C++ forum but I base my question on the notion that I
confidence in my C skills and that there is an underlying cause for the choice of PHP developers to
save Bucket data the way they do.If I am mistaken in posting this here please let me know.
I came to ponder this when working with hash functions (zend_hash_find,zend_hash_add) and I saw that
zend_hash_add (macro for _zend_hash_add_or_update) accepts pData as void * but is usually passed an
address of a pointer like in:
zend_class_entry *ce;zend_hash_add(CG(class_table), "class_name",class_length+1, &ce);
pData is in turn memcpy'd into a Bucket's pData element which is also void *, passing the
&ce suggests that what will get memcpy'd will be the contents of &ce which is in turn
the address pointed to by ce, the address of a zend_class_entry struct, this suggests that the
Bucket's pData element though marked as void * actually servs as a void ** (since it points to
an adress which should be dereferenced as a pointer).
I validated this by looking at zend_hash_find which accepts pData as void **, this time pData is to
hold the address for the data retrieved by zend_hash_find, this time I noticed the function call to
be :
zend_class_entry **ce;zend_hash_find(CG(class_table), "class_name", class_length+1, (void
**) &ce);
and the data assigned to pData is :*pData = Bucket->pData;
By my logic by setting *pData I am setting the data held at the address in pData itself which is
&ce, this sets ce to point to an address of Bucket->pData which as I established earlier is
used as a void **.
I may be missing some basic understanding in pointers but I am pretty confident that this is not the
case and thus I am asking is there a specific reason to use this sort of 'trickery'
instead of of explicitly using void *, I fail to see the harm in Bucket->pData being a pointer
to the data itself and the needed casts to be done instead of the current situtaiton where it points
to another address.
Thank you for any light you can shed on this.