@@ -134,13 +134,21 @@ check by comparing the reference count field to the immortality reference count.
134134 { _Py_IMMORTAL_REFCNT }, \
135135 (type) \
136136 },
137- #else
137+ #elif !defined( __cplusplus )
138138#define PyObject_HEAD_INIT (type ) \
139139 { \
140140 _PyObject_EXTRA_INIT \
141141 { 1 }, \
142142 (type) \
143143 },
144+ #else
145+ // gh-105059: In C++, ob_refcnt type is Py_ssize_t
146+ #define PyObject_HEAD_INIT (type ) \
147+ { \
148+ _PyObject_EXTRA_INIT \
149+ 1, \
150+ (type) \
151+ },
144152#endif /* Py_BUILD_CORE */
145153
146154#define PyVarObject_HEAD_INIT (type , size ) \
@@ -165,12 +173,18 @@ check by comparing the reference count field to the immortality reference count.
165173 */
166174struct _object {
167175 _PyObject_HEAD_EXTRA
176+ #ifndef __cplusplus
168177 union {
169178 Py_ssize_t ob_refcnt ;
170179#if SIZEOF_VOID_P > 4
171180 PY_UINT32_T ob_refcnt_split [2 ];
172181#endif
173182 };
183+ #else
184+ // gh-105059: In C++, avoid anonymous union for ob_refcnt.
185+ // C++ uses opaque function calls for Py_INCREF() and Py_DECREF().
186+ Py_ssize_t ob_refcnt ;
187+ #endif
174188 PyTypeObject * ob_type ;
175189};
176190
@@ -611,15 +625,18 @@ PyAPI_FUNC(void) _Py_DecRef(PyObject *);
611625static inline Py_ALWAYS_INLINE void Py_INCREF (PyObject * op )
612626{
613627#if defined(Py_LIMITED_API ) && (Py_LIMITED_API + 0 >= 0x030c0000 || defined(Py_REF_DEBUG ))
614- // Stable ABI implements Py_INCREF() as a function call on limited C API
615- // version 3.12 and newer, and on Python built in debug mode . _Py_IncRef()
616- // was added to Python 3.10.0a7, use Py_IncRef() on older Python versions.
617- // Py_IncRef() accepts NULL whereas _Py_IncRef() doesn't.
628+ // In limited C API version 3.12 and newer and on Python built in debug
629+ // mode, Py_INCREF() is implemented as a function call . _Py_IncRef() was
630+ // added to Python 3.10.0a7, use Py_IncRef() on older Python versions.
631+ // Py_IncRef() accepts NULL, whereas _Py_IncRef() doesn't.
618632# if Py_LIMITED_API + 0 >= 0x030a00A7
619633 _Py_IncRef (op );
620634# else
621635 Py_IncRef (op );
622636# endif
637+ #elif defined(__cplusplus )
638+ // gh-105059: In C++, Py_INCREF() is implemented as a function call
639+ _Py_IncRef (op );
623640#else
624641 // Non-limited C API and limited C API for Python 3.9 and older access
625642 // directly PyObject.ob_refcnt.
@@ -649,10 +666,10 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
649666#endif
650667
651668#if defined(Py_LIMITED_API ) && (Py_LIMITED_API + 0 >= 0x030c0000 || defined(Py_REF_DEBUG ))
652- // Stable ABI implements Py_DECREF() as a function call on limited C API
653- // version 3.12 and newer, and on Python built in debug mode . _Py_DecRef() was
654- // added to Python 3.10.0a7, use Py_DecRef() on older Python versions.
655- // Py_DecRef() accepts NULL whereas _Py_IncRef () doesn't.
669+ // In limited C API version 3.12 and newer and on Python built in debug mode,
670+ // Py_DECREF() is implemented as a function call . _Py_DecRef() was added to
671+ // Python 3.10.0a7, use Py_DecRef() on older Python versions. Py_DecRef()
672+ // accepts NULL, whereas _Py_DecRef () doesn't.
656673static inline void Py_DECREF (PyObject * op ) {
657674# if Py_LIMITED_API + 0 >= 0x030a00A7
658675 _Py_DecRef (op );
@@ -662,6 +679,13 @@ static inline void Py_DECREF(PyObject *op) {
662679}
663680#define Py_DECREF (op ) Py_DECREF(_PyObject_CAST(op))
664681
682+ #elif defined(__cplusplus )
683+ // gh-105059: In C++, Py_DECREF() is implemented as a function call
684+ static inline void Py_DECREF (PyObject * op ) {
685+ _Py_DecRef (op );
686+ }
687+ #define Py_DECREF (op ) Py_DECREF(_PyObject_CAST(op))
688+
665689#elif defined(Py_REF_DEBUG )
666690static inline void Py_DECREF (const char * filename , int lineno , PyObject * op )
667691{
0 commit comments