5

In python's source code, there are some macro definitions like this:

#define PyObject_HEAD    \
    int ob_refcnt;       \
    struct _typeobject *ob_type;


#define PyObject_VAR_HEAD  \
    PyObject_HEAD          \
    int ob_size; 


typedef struct _object {  
    PyObject_HEAD  
} PyObject;    

typedef struct _object {  
    PyObject_HEAD   
    long ob_ival;   
} PyIntObject;   

typedef struct {   
    PyObject_VAR_HEAD   
} PyVarObject;   

The question is, why PyObject* can point to each object(such as PyIntObject, PyVarObject) in python?

Jens
  • 69,818
  • 15
  • 125
  • 179
米雪儿
  • 71
  • 4

2 Answers2

12

Each struct for the different types of Python object has an instance of PyObject_HEAD as its first member (or the first member of its first member, and so on).

This member sub-object is guaranteed to be located at the same address as the full object.

The PyObject_HEAD* points at that member sub-object, but could be cast to the full type once ob_type has been inspected to work out what the full type is.

This trick isn't unique to CPython -- it's often used to implement a limited kind of inheritance in C. Basically you model the "is a X" relationship by "has a X at the start of".

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • In [this](https://docs.python.org/3/c-api/structures.html#c.PyObject), it mentioned Py_REFCNT, Py_TYPE and Py_SIZE macros, but no #define's like Py_REFCNT(x) (x->ob_type). Can someone show their source code or the link to it? – Leon Chang Aug 02 '22 at 22:51
2

Because PyObject_HEAD is ALWAYS the first struct member not affected by the concrete underlying type. The pointer will ofcourse get casted.

Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77