前面学习了C的共同体union与结构体struce, 这次再来看下php中zval的具体大小
struct _zval_struct {zend_value value;/* value */union {struct {ZEND_ENDIAN_LOHI_4(zend_uchar type,/* active type */zend_uchar type_flags,zend_uchar const_flags,zend_uchar reserved) /* call info for EX(This) */} v;uint32_t type_info; // 4字节} u1;union {uint32_t next; //4字节 /* hash collision chain */uint32_t cache_slot; /* literal cache slot */uint32_t lineno; /* line number (for ast nodes) */uint32_t num_args; /* arguments number for EX(This) */uint32_t fe_pos; /* foreach position */uint32_t fe_iter_idx; /* foreach iterator index */uint32_t access_flags; /* class constant access flags */uint32_t property_guard; /* single property guard */uint32_t extra; /* not further specified */} u2;};
包括三个部分一个union的u1, union的u2及 zend_value
这里uint32_t是无符号int,占4个字节, zend_uchar实际是char占一个字节
可以看到u1 中的type_info 4个字节,v是结构体里面是四个zend_uchar总共是4个字节,因此u1占4个字节。
u2同理uint32_t同样占4个字节
u1、u2各占4个字节,再来看zend_value
typedef union _zend_value {zend_long lval;/* long value */double dval;/* double value */zend_refcounted *counted;zend_string *str;zend_array *arr;zend_object *obj;zend_resource *res;zend_reference *ref;zend_ast_ref *ast;zval *zv;void *ptr;zend_class_entry *ce;zend_function *func;struct {uint32_t w1;uint32_t w2;} ww;} zend_value;
可以看到zend_value是一个union, zend_long其实是int64_t 占8字节, double占8字节,ww为struct两个uint32_t总共占8字节,中间的全部为指针类型大小为8字节,因此整个zend_value占8字节。
所有zval中value 8字节、u1 4字节、u2 4字节, 总共16字节