前面学习了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字节